0

我的代码有问题。我收到 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”行中得到错误,然后程序停止。

4

2 回答 2

3

您需要为您的类定义一个复制构造函数赋值运算符

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

否则,你就违反了三原则

这段代码...

c = a + b;

可能会产生暂时myString持有的价值a + b

默认生成的复制和赋值实现将给出与临时对象c 相同的string_指针。

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

巧合的是,这段代码:

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

永远不会采取不同的行动,而不是简单地:

delete [] this->string_;
于 2013-04-01T17:55:02.500 回答
1

你没有显示类定义,但我猜你没有遵循三规则

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

最简单的解决方案是使用旨在为您管理内存的类。std::string或者std::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 中,为了获得更多奖励积分,还可以考虑提供移动构造函数和赋值运算符。这些只需要修改指针,所以会比复制效率高得多。

于 2013-04-01T17:57:00.463 回答