堆和类析构函数

时间:2013-04-01 17:36:08

标签: c++ class heap destructor

我的代码有问题。我收到BLOCK_TYPE_IS_VALID错误...我知道new和delete有问题,但我找不到它。 我有一个带有这些函数的myString类:

    //constructors and destructors
myString::myString() {
    this->string_ = NULL;
    this->length = 0;

    cout << "created " << "NULL" << endl;
}

myString::myString(char a[]) {
    int i;
    for (i=0; a[i]!=NULL; i++);
    this->length = i;

    int j=0;
    while(pow(2,j)<i)
        j++;

    this->string_ = new char [(int)pow(2,j)];
    for (int i=0; i<this->length; i++)
        this->string_[i] = a[i];

    cout << "created " << this->string_ << endl;
}

myString::~myString() {
    cout << "deleteing " << this->string_ << endl;
    if (this->string_ != NULL)
        delete [] this->string_;
}

当我运行这个

myString a("aaa");
myString b("bbbb");
myString c;
c = a + b;
cout << c.get_lenght() << endl;
cout << c.get_string() << endl;

我在“c = a + b”行中得到错误,然后程序停止。

2 个答案:

答案 0 :(得分:3)

您需要为您的班级定义copy constructorassignment operator

myString::myString( const myString& );
myString& operator=( const myString& );

否则,您违反了rule of three

此代码......

c = a + b;

可能会产生一个持有myString值的临时a + b

默认生成的副本和作业实现将为c 提供临时具有的string_指针

当运行其中任何一个字符串的析构函数时,另一个字符串将有一个悬空指针。

巧合的是,这段代码:

if (this->string_ != NULL)
    delete [] this->string_;

永远不会采取与简单不同的行为:

delete [] this->string_;

答案 1 :(得分:1)

您没有显示课程定义,但我猜您没有关注Rule of Three

如果没有正确实现的复制构造函数和复制赋值运算符,则无法安全地复制对象。默认实现将简单地复制指针(和其他成员变量),使两个副本在其析构函数中删除相同的内存块。

最简单的解决方案是使用专为您管理内存的类。 std::stringstd::vector<char>在这里是理想的。

假设您有充分的理由自己管理内存,则需要以下内容:

// Copy constructor
myString(myString const & other) :
    string_(new char[other.length]),
    length(other.length)
{
    std::copy(other.string_, other.string_+length, string_);
}

// Simple assignment operator
// For bonus points (and a strong exception guarantee), use the copy-and-swap idiom instead
myString & operator=(myString const & other) {
    if (this != &other) {
        delete [] string_; // No need to check for NULL (here or in the destructor)
        string_ = new char[other.length];
        length = other.length;
        std::copy(other.string_, other.string_+length, string_);
    }
    return *this;
}

在C ++ 11中,对于更多的奖励积分,还要考虑提供移动构造函数和赋值运算符。这些只需要修改指针,因此比复制更有效。