繁体   English   中英

析构函数被调用两次,而没有复制构造函数或赋值运算符被调用

[英]Destructor Called Twice While No Copy Constructor or Assignment Operator Gets Callled

我有一个 class:

class A
{
public:
    A()
    {
        std::cout << "Constructor called" << std::endl;
    }

    ~A()
    {
        std::cout << "Destructor called" << std::endl;
    }

    A(const A& another)
    {
        std::cout << "Copy constructor called" << std::endl;
    }

    A& operator=(const A& another)
    {
        std::cout << "Assignment operator= called" << std::endl;
    }
};

在我非常复杂的项目中,我在启动我的应用程序后得到了以下 output:

Constructor called

但是当我Ctrl+C 终止我的应用程序时:

Destructor called
Destructor called

并且在整个过程中,没有调用复制构造函数或赋值运算符。

我的 class A有动态 memory 分配,我必须在析构函数中释放它,但是析构函数被调用了两次,这很糟糕。

我不知道什么会导致这个问题。

我用谷歌搜索并搜索了很多。 很多关于“两次调用析构函数”的问题是因为隐式调用了复制构造函数(赋值运算符)。

谢谢。

彼得

如果你以某种方式调用了析构函数两次,也许你有两个对象认为它们通过指针拥有它。

如果您确实有两个对象认为它们拥有这个,请考虑使用引用计数指针,例如 Boost::shared_ptr 或 tr1::shared_ptr 来包含它。 这样你就不必担心最终谁调用了析构函数。

除了调试器,您可以尝试 Valgrind (memcheck) 来查找您的程序删除已释放 object 的位置。 在这种情况下,它可能不会提供比调试器更多的细节,但你迟早应该学会使用 Valgrind (memcheck)。

另一个偏执的策略是确保在删除 NULL 后将任何内部指针设置为它们。

很可能您有另一个未显示的构造函数,或者您多次调用析构函数,无论是显式还是通过delete

在这种情况下,调试器或额外的cout会比我们更有帮助。

就我而言,我没有使用指针,但析构函数仍然被调用了两次。 我为解决这个问题所做的是覆盖复制赋值 operator MyClass& operator=(const MyClass& other) 不太清楚为什么自动生成的运算符会导致问题,但似乎确实如此。

在析构函数中插入断点。 然后,无论何时调用它,您都可以获取堆栈跟踪并查看它是从哪里调用的。

编辑:

可以期望复制省略对这些琐碎的调试语句造成严重破坏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM