【问题标题】:Which destructor is called when in C++?在 C++ 中调用哪个析构函数?
【发布时间】:2010-12-22 10:46:17
【问题描述】:

我正在寻找程序中的内存泄漏。

我把它缩小到一些没有被调用的析构函数。但是,我不知道为什么:

class CMain : public CList {
public:
    CMain();
    virtual ~CMain();
    ...
}

class CList : public CProc {
public:
    CList();
    virtual ~CList();
    ...
}

/* some code and a main func here */
CMain *pMain = new CMain();
/* some more code here */
delete pMain;

CMain 可以很好地释放,但永远不会调用 ~CList()CList 的所有父类也都有虚拟析构函数。

你有什么提示为什么 CList 的析构函数从未被调用?

【问题讨论】:

  • 当你说CMain gets deallocated just fine时,你的意思是CMain::~CMain被执行但CList::~CList没有被执行?如果是这样,你如何销毁对象 - 使用delete o;
  • 你怎么知道没有调用特定的析构函数?
  • @sharptooth:我在析构函数中放了一个断点和一些控制台输出。

标签: c++ destructor


【解决方案1】:

你可以在 ~CMain 中设置一个断点来查看它的去向吗?

【讨论】:

  • 多哈。我只进入了 ~CMain 几步。但你是对的。它永远不会到达 ~CMain 的末尾。
  • 恭喜。然后再进行一些调试,你可能最终会发现为什么它没有被调用。 PS:检查反汇编代码可能会有所帮助。
【解决方案2】:

也许某处存在切片问题。只是猜测..

What is object slicing? 不,不是这样的。

你应该在 ~CMain 中放置一个 try catch 块,嗯,它的一个成员在析构函数中抛出异常?

【讨论】:

  • 什么意思?什么是切片问题?
  • 如果是切片问题,那么派生类析构函数将不会被调用,不是吗?但这里似乎没有调用基类析构函数。
【解决方案3】:

因为你没有delete你的对象分配了new

;-)

更严重的是,你是否已经调试了你的一个 CList 的理论范围的结束,并进入了它的销毁过程,会发生什么?

【讨论】:

    【解决方案4】:

    CMain 被释放得很好,但 ~CList() 永远不会被调用。

    这听起来像是一个错误的说法。如果~CMain 被调用,那么~CList 最终也会被调用,因为它是一个基类。检查您如何检测是否调用了析构函数。

    当你说“CMain 被释放”时,你的意思是说你在上面发出delete 吗?检查在您执行delete pMain 时,CMain 的类定义是可见的。在没有定义的情况下,允许编译器假定该类没有用户定义的或虚拟的析构函数,并且可以省略调用它。

    【讨论】:

      【解决方案5】:

      孩子,然后是父母。但是在它们之间,孩子的属性被破坏了。我建议查看 ~CMain 是否运行到最后 - 如果是,并且 ~CList 从未输入,则说明 CMain 的属性之一有问题。

      只是为了演示:

      #include <iostream>
      #include <stdlib.h>
      
      struct Owned {
          ~Owned() {
              std::cerr << "~Owned" << std::endl;
              exit(1);
          }
      };
      
      struct Parent {
          virtual ~Parent() {
              std::cerr << "~Parent" << std::endl;
          }
      };
      
      struct Owner : public Parent {
          ~Owner() {
              std::cerr << "~Owner" << std::endl;
          }
      
          Owned owned;
      };
      
      int main()
      {
          Owner owner;
          return 0;
      }
      

      输出:

      ~Owner
      ~Owned
      

      并以返回码 1 退出。

      【讨论】:

        猜你喜欢
        • 2015-08-13
        • 2016-10-28
        • 2013-01-06
        • 2014-05-03
        • 1970-01-01
        • 2020-04-10
        • 2018-06-02
        • 2021-07-19
        • 2017-04-28
        相关资源
        最近更新 更多