0

我试图了解操作员重载但遇到了问题。该程序仅用于 cons 两个字符串。我知道已经有其他方法可以做到这一点,但我想玩。我收到以下错误:

文件: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

4 回答 4

1

第一个警告信号:你的类的析构函数做了一些delete事情,但该类没有定义复制构造函数或复制赋值运算符。

三法则

您可能不小心制作了对象的临时副本,并在调用临时析构函数时弄乱了它们。

于 2010-12-03T16:06:23.447 回答
1

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

于 2010-12-03T16:06:26.487 回答
0

你需要做两件事:

  1. 创建一个复制构造函数,该构造函数创建自己的数据副本
  2. 通过引用传递,而不是价值传递。

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

于 2010-12-03T16:05:16.270 回答
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

于 2010-12-03T16:54:38.043 回答