在什么情况下C ++析构函数不会被调用? [英] Under what circumstances are C++ destructors not going to be called?

查看:164
本文介绍了在什么情况下C ++析构函数不会被调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我知道我的析构函数在堆栈的正常展开时被调用,当抛出异常时,而不是当exit()被调用时。哪里的析构函数不会被调用? SIGINT或SIGSEGV等信号怎么办?我假设对于SIGSEGV,它们不被调用,但是对于SIGNINT,我们如何知道哪些信号会释放堆栈?



是否有其他情况不会被调用?

解决方案








  1. 长跳转:这些干扰了自然堆栈展开过程,并且经常导致C ++中的未定义行为。

  2. 过早退出(你已经指出了这些,但是值得注意的是,的异常被抛出导致未定义的行为,这就是为什么我们不应该抛出dtors)

  3. 抛出一个构造函数不会调用一个类的dtor。这就是为什么,如果你在一个ctor中分配由多个不同指针(而不是智能指针)管理的多个内存块,你需要使用函数级try块或避免使用初始化器列表,并在ctor中有一个try / catch块身体(或者更好的是,只是使用一个聪明的指针,像scoped_ptr,因为任何成功初始化到目前为止的初始化列表中的成员将被销毁,即使类dtor不会被调用)。

  4. 指出,当通过基指针删除类时,无法创建一个dtor虚拟函数可能无法调用子类dtors(未定义的行为)。

  5. 无法调用匹配操作符delete / delete [ ]为运算符new / new []调用(未定义的行为 - 可能无法调用dtor)。

  6. 在取消分配中使用自定义内存分配器时使用placement new时手动调用dtor

  7. 使用像memcpy这样的函数,只将一个内存块复制到另一个内存块而不调用复制转换器。 mem *函数在C ++中是致命的,因为它们推翻了类的私有数据,覆盖了vtables等。结果通常是未定义的行为。

  8. 实例化一些智能指针(auto_ptr)对于不完整类型,请参阅此讨论


I know that my destructors are called on normal unwind of stack and when exceptions are thrown, but not when exit() is called.

Are there any other cases where my destructors are not going to get called? What about signals such as SIGINT or SIGSEGV? I presume that for SIGSEGV, they are not called, but for SIGNINT they are, how do I know which signals will unwind the stack?

Are there any other circumstances where they will not be called?

解决方案

Are there any other circumstances where they[destructors] will not be called?

  1. Long jumps: these interfere with the natural stack unwinding process and often lead to undefined behavior in C++.
  2. Premature exits (you already pointed these out, though it's worth noting that throwing while already stack unwinding as a result of an exception being thrown leads to undefined behavior and this is why we should never throw out of dtors)
  3. Throwing from a constructor does not invoke the dtor for a class. This is why, if you allocate multiple memory blocks managed by several different pointers (and not smart pointers) in a ctor, you need to use function-level try blocks or avoid using the initializer list and have a try/catch block in the ctor body (or better yet, just use a smart pointer like scoped_ptr since any member successfully initialized so far in an initializer list will be destroyed even though the class dtor will not be called).
  4. As pointed out, failing to make a dtor virtual when a class is deleted through a base pointer could fail to invoke the subclass dtors (undefined behavior).
  5. Failing to call matching operator delete/delete[] for an operator new/new[] call (undefined behavior - may fail to invoke dtor).
  6. Failing to manually invoke the dtor when using placement new with a custom memory allocator in the deallocate section.
  7. Using functions like memcpy which only copies one memory block to another without invoking copy ctors. mem* functions are deadly in C++ as they bulldoze over the private data of a class, overwrite vtables, etc. The result is typically undefined behavior.
  8. Instantiation of some of smart pointers (auto_ptr) on an incomplete type, see this discussion

这篇关于在什么情况下C ++析构函数不会被调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆