我有类Egg
,我有预定义的构造函数。这是我的operator =和析构函数的样子:
Egg& Egg::operator=(const Egg& rhs)
{
if (this == &rhs)
return *this;
size = rhs.size;
name = rhs.name;
return *this;
}
Egg::~Egg()
{
size = 0;
delete[] name;
}
我想做的是一个动态的鸡蛋阵列,每当我创造一个新的鸡蛋时,它就会延伸。我是这样做的:
Egg* eggArr = NULL;
void createEgg()
{
Egg * temp = eggArr;
eggArr = new (std::nothrow) Egg[eggsCnt + 1];
if (!eggArr)
{
std::cerr << "No memory!\n";
return;
}
for (size_t i = 0; i < eggsCnt; ++i)
{
eggArr[i] = temp[i];
std::cout << eggArr[i].getName();
}
eggArr[basketCnt].setName(eggsCnt, eggArr);
eggsCnt++;
delete[] temp; //problematic line
}
如果我删除delete [] temp,代码可以正常工作,但是存在内存泄漏。 当它停留在程序上时,由于某种原因我的eggArr也被破坏了,然后当我试图接触它的一些成员时,它们是未定义的。我的析构函数,运算符=或其他地方的问题是什么?
答案 0 :(得分:2)
你有问题:
Egg& Egg::operator=(const Egg& rhs)
{
name = rhs.name;
...
}
Egg::~Egg()
{
...
delete[] name;
}
之后
Egg egg1, egg2;
egg1 = egg2;
name
和egg1
中的egg2
值相同。当他们将要调用它们的析构函数时,它将被删除两次 - 这是一条通往地狱的直接道路。
这是另一个例子,稍微复杂一些:
Egg egg1;
{
Egg egg2;
egg2 = egg1;
}
std::cout << egg1.getName() << "\n";
在第二个示例中,一旦egg2
离开了它的范围,name
就会被删除 - 并且它与name
共享的egg1
相同。结果,egg1.getName()
将尝试使用已经删除的指针,这也是好的程序员不会参与的事情。
您的复制构造函数和您的代码可能存在同样的问题,解决方案是停止对name
执行任何操作并使其成为正确的类型 - 判断为名称std::string
似乎合适。