【问题标题】:heap and class destructor堆和类析构函数
【发布时间】:2013-03-22 19:38:15
【问题描述】:

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

【问题讨论】:

  • 您需要在您的类中定义operator+,以便程序知道如何添加字符串。
  • 您是否重载了运算符+ & 运算符=?你能显示那个代码吗?
  • 根据我看到的代码,希望你已经定义了拷贝构造函数和赋值运算符。你能显示那个代码吗?
  • 避免使用int pow2 = 1; while (pow2 &lt; i) pow2 *= 2; 调用 pow 您可能还希望将此数字作为容量变量保留在您的班级中。

标签: c++ class heap-memory destructor


【解决方案1】:

你没有显示类定义,但我猜你没有遵循Rule of Three

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

最简单的解决方案是使用旨在为您管理内存的类。 std::stringstd::vector&lt;char&gt; 是这里的理想选择。

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

// 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 中,为了获得更多奖励积分,还可以考虑提供移动构造函数和赋值运算符。这些只需要修改指针,所以会比复制效率高很多。

【讨论】:

    【解决方案2】:

    您需要为您的班级定义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_;
    

    【讨论】:

    • 谢谢,我很困惑。现在我明白会发生什么了。
    猜你喜欢
    • 2016-08-23
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    • 2013-07-07
    • 1970-01-01
    • 2011-09-01
    相关资源
    最近更新 更多