两次调用析构函数会导致崩溃

时间:2015-07-23 14:27:29

标签: c++

我实现了一个构造函数,它接受一个字符串作为参数,这会导致析构函数被调用两次然后程序崩溃(程序包含一个原始指针)。我知道它与复制构造函数有关,当使用这种类型的构造函数时,它会以某种方式被调用。下面是一个简单的代码,说明了这个问题。

我很感激您对如何修复程序以避免崩溃的评论。我需要使用这种构造函数。 我想了解为什么复制构造函数被调用。我没有做任何明确的任务。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

class DebugClass
{
public:
    DebugClass(void) {
        data = NULL;
    }

    DebugClass(std::string str) {
        data = new double[2];
        data[0] = 1.0;
        data[1] = 2.0;
    }

    DebugClass(DebugClass const& other) {
        cout << "copy construction\n"; 
    }

    ~DebugClass(void) {
        if (data)
        {
            delete [] data;
            data = NULL;
        }
    }

    double* data;
};


int main()
{
    DebugClass obj = DebugClass("Folder");
    return 0;
}

2 个答案:

答案 0 :(得分:6)

您的副本构造函数离开data未初始化:

DebugClass::DebugClass(DebugClass const& other) 
{ 
    cout << "copy construction\n"; 
}

因此,从该点开始使用任何数据都会产生不确定的行为。

如果您只是将data设置为nullptr,那么您就不应该进行双重删除。虽然您可能真的想从other进行某种形式的复制。

这一行:

DebugClass obj = DebugClass("Folder");

导致复制构造函数被构造为构造obj

的一部分

如果您改为:

DebugClass obj("Folder");

然后obj将使用普通构造函数构建。

答案 1 :(得分:1)

DebugClass obj = DebugClass("Folder");

rhs创建一个无名对象并分配给obj,这是另一个新对象创建,因此调用了复制构造函数。

您的陈述相当于

DebugClass obj1;
DebugClass obj2 = obj1; // here copy-ctor gets invoked

对于第二部分......虽然你已经定义了一个复制程序,但它对你的程序几乎没有好处,因为你没有对指针数据成员做任何事情,而这个成员是未初始化的。这导致了不确定的行为。

虽然我不知道你对类DebugClass的意图,但是以更简单的方式可以使用另一个数据成员array_size定义它,你可以如下所示。

    DebugClass(void):array_size(0) {
    data = NULL;
}

DebugClass(std::string str, size_t aSize):array_size(aSize)
{
    if(array_size)
    {
       data = new double[array_size];
       data[0] = 1.0;
       data[1] = 2.0;
    }
}

DebugClass(DebugClass const& other):array_size(other.array_size)
{
    cout << "copy construction\n"; 
    if(array_size)
    {
       data = new double[array_size];
       for(int i=0; i<array_size; i++)
           data[i] = other.data[i];
    }
}

希望这澄清。