我对以下课程有疑问。我认为问题在于字符串数组,因为我做了两个其他的类,问题是相同的。当我运行该程序时,它会抛出“双重自由或腐败”,但我不认为任何双重腐败是可能的。输入字符串作为引用或Add方法中的常见参数存在同样的问题。
class WareH
{
public:
WareH(void)
{
first = true;
rows = 1;
inLine = 0;
cnt = 0;
max = 2;
cL = 0;
strs = new string[max];
}
~WareH(void)
{
delete [] strs;
}
bool Add(string& str, int ending)
{
if (first)
inLine++;
else
cL++;
if (ending == 0)
{
if (first)
first = false;
if (cL != inLine)
return false;
rows++;
}
strs[cnt++] = str;
Bigger();
return true;
}
void Bigger(void)
{
if(max == cnt)
{
max *= 2;
string* tmp = new string[max];
for (int i = 0; i < cnt; i++)
tmp[i] = strs[i];
delete [] strs;
strs = tmp;
}
}
friend ofstream& operator<<(ofstream& of,WareH war)
{
for (int a = 0; a < war.cnt; a++)
of << war.strs[a] << endl;
return of;
}
private:
bool first;
int rows, inLine, cnt, max, cL;
string* strs;
};
答案 0 :(得分:1)
当一个类管理资源并在其析构函数中释放它们时,必须考虑Rule of Three以确保复制对象不会导致两个对象管理同一资源。
这就是这里发生的事情:默认的复制构造函数和复制赋值运算符将复制指针,为您提供两个对象,它们都会在销毁时尝试删除相同的数组。解决方案是:
std::vector
而不是自己管理内存分配。答案 1 :(得分:0)
当我运行该程序时,它会抛出“双重自由或腐败”,但我不认为任何双重腐败是可能的。
受过教育的猜测:
问题不在于您显示的代码中,而是在客户端代码中。这就是我认为发生的事情:
您编写的客户端代码实例化(或通过值分配或返回或在std容器中存储)WareH
实例,并且因为您没有定义复制构造函数和赋值运算符(请参阅“The Big Three “),他们最终复制源对象中的值。当删除这些实例中的第一个(彼此分配)时,它们将删除strs指针。
当第二个实例被删除时,它们会删除之前删除的相同的strs指针(因为默认的复制构造函数和赋值运算符不会复制已分配的内存,只是复制指针)。
解决方案(如果确实存在问题):
工作(和不好)解决方案:为您的班级明确定义复制构造和赋值运算符。
工作(和良好)解决方案:将您的strs
实施为std::vector<std::string>
,而不是std::string*
和cnt
。