在类中重载+ - Debug Assertion失败!

时间:2010-12-03 16:01:55

标签: c++ debugging visual-c++ dynamic-arrays

我试图了解运算符重载但遇到了问题。该程序只是意味着两个字符串。我知道还有其他方法可以做到这一点,但我想玩。我收到以下错误:

文件:dbgdek.cpp 行:52 _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse));

我认为这与我使用delete []有关。请帮助我真的卡住了。

#include <iostream>
using namespace std;

class list{
public:
 char *value;
 int size;
 list(int s){size=s; allocmem();};
 ~list(){delete [] value;};
 list operator+(list);
private:
 void allocmem(void);
};

void list::allocmem(void){
 value=new char[size];
}

list list::operator+(list a)
{
 list t(a.size+size);
 for (int i=0; i<a.size; i++){
      t.value[i]=a.value[i];
 }
 for (int i=a.size; i<t.size; i++){
      t.value[i]=a.value[i-a.size];
 }
 return t;
}

int main ()
{
     list a(2),b(2),c(4);
     a.value[0]='a';
     b.value[0]='b';
     a.value[1]='c';
     b.value[1]='d';
     c=a+ b;
     for (int i=0; i<c.size; i++){
          cout<<c.value[i];
     }
     system("pause");
     return 0;
}

请帮忙!

4 个答案:

答案 0 :(得分:1)

第一个警告标志:您的类的析构函数执行了一些delete,但该类没有定义复制构造函数或复制赋值运算符。

请参阅Rule of Three

在调用临时析构函数时,您可能会意外地制作对象的临时副本并弄乱它们。

答案 1 :(得分:1)

您需要为类定义赋值运算符(list::operator=(list const&))和复制构造函数(list::list(list const&)),以避免在析构函数中重复删除内存。如果您没有定义这些函数,编译器将使用这些函数的默认生成版本,这实际上创建了列表对象的按位副本。这是灾难性的,因为在复制列表实例后,两个实例都将具有相同的指针值,从而导致重复删除。

答案 2 :(得分:0)

你需要做两件事:

  1. 创建一个复制构造函数,用于创建自己的数据副本
  2. 通过引用传递,而不是值。
  3. 您正在operator +()中传递值。这将传递对象的副本(不是您想要的;您想要传递引用)。但是因为您没有创建复制构造函数,复制的对象将获得默认的成员复制 - 现在2个对象具有相同的指针。第一个删除它很好,第二个对象现在有一个无效的指针。

答案 3 :(得分:0)

为什么不使用char*而不是直接使用std::string字符串?然后你不必担心内存管理问题(在这种情况下,由于没有像其他人那样实现复制构造函数而导致双重删除)。在最直接的翻译中,就像:

class list
{
public:
 std::string value;
 int size;
 list(int s){size=s; allocmem();}
 ~list(){}
 list operator+(list);
private:
 void allocmem(void);
};


void list::allocmem(void){
 value.resize(size);
}

请注意,几乎可以肯定使用string更好的实现(例如size可以消失)。此外,您可能不应拥有所有属性public