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

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

问题描述

我知道我的析构函数是在正常展开堆栈的时候调用的,当异常被抛出时,而不是在exit()被调用时。



还有其他的情况我的析构函数不会被调用? SIGINT或SIGSEGV等信号呢?我认为对于SIGSEGV来说,它们不被叫做,但是对于SIGNINT来说,我们如何才能知道哪些信号可以解开堆栈?



有没有其他的情况呢不会被调用?

解决方案



有没有其他情况他们[析构函数]不会被调用?






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

  2. 提前退出(您已经指出了这些,但是值得注意的是,在堆栈展开过程中投掷结果抛出异常导致未定义的行为,这就是为什么我们不应该抛弃dtors)

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

  4. As指出,当通过基本指针删除类时,不能使dtor虚拟化,可能无法调用子类dtors(未定义的行为)。

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

  6. 在deallocate中使用自定义内存分配器使用placement new时无法手动调用dtor部分。

  7. 使用像memcpy这样的功能,只能将一个内存块复制到另一个而不调用副本c职权范围。 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天全站免登陆