Why do I get: double free or corruption (top) after running this c++ script?
我有以下代码:
与
作为唯一的公共场所
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| istream& operator>>(istream& i, Chain& s) {
delete [] s.c;
const int L = 256;
char *t = new char[L];
i.getline(t,L);
s.c = t;
return i;
}
ostream& operator<<(ostream& o, Chain s) {
o << s.c;
return o;
}
#include <iostream>
#include"Chain.h"
using namespace std;
int main(){
Chain id;
cin >> id;
cout << id;
cout << id; |
在Xubuntu(最新版本)上的Eclipse IDE下运行代码后,出现以下错误:
Error in [...] double free or corruption (top): 0x00000000008fd290 ***
有什么事吗
-
请发布MCVE。
-
请提供一个最小的可复制示例。该问题的每个答案都将包含有关Chain内部的猜测,这很糟糕。
-
我的建议是在删除c之后,始终将其设置为nullptr(或NULL或0)。这样,它将永远不会被双重删除。
-
@GrahamS这可能在这里无济于事,因为OP可能会破坏副本构造函数。
-
如果这个问题处于可回答的状态,则很可能会因为stackoverflow.com/questions/4172722/what-is-the-rule-of-three
-
是的,公平点@BaummitAugen
-
Whyyyyyyy为此进行原始动态分配?为何还要三票?
-
@ user3166611要节省您一些时间:使用std :: string代替char *。像这样的原始拥有指针不会像std :: string和std :: vector这样的标准类那样管理自己的内存。当涉及到原始指针时,很容易意外地双重删除内容(如您所做的那样),而在没有原始指针时几乎是不可能的。除非您完全理解诸如三定律之类的内容,否则不要尝试使用原始数组或原始拥有的指针编写类。
-
亚伯:这两行不是代码。
-
@Abel:拜托,拜托,请不要将非代码格式化为代码,否则它完全不可读。
-
@LightnessRacesinOrbit,哈哈,你是什么意思?哦,废话,我看到了:/(虽然还是不可读,现在改进了)
1
| ostream& operator<<(ostream& o, Chain s) { |
这不是对s的引用,它正在构建一个完整的副本,其中可能包含一个析构函数,该析构函数会删除所使用的内存。 而且由于您两次调用它,因此它两次被删除。
-
可能是真的。但是,在需要猜测的情况下回答问题仍会给OP留下错误的印象。请尽量避免回答问题,直到它们正确形成为止!
-
我认为通灵的远程调试超级棒而且很棒!
-
@LightnessRacesinOrbit,这是C ++,不是魔术8球。给定显示的代码和结果,我非常确定我的回答,这足以至少启动调试会话。
-
@Blindy:好吧,正好:堆栈溢出问题不是调试会话。
您的类Chain很可能具有销毁c的析构函数。 所以在这一行:
您要删除c,然后在删除Chain时,它会再次尝试销毁c,以发现它已被删除,并且您正在执行双重释放。
-
是的,我有那个析构函数,应该删除它吗?
-
不,即使删除了析构函数,C ++也会默认为您创建一个。最好定义一个,以便知道删除什么/如何删除。
-
@ user3166611:所要做的就是导致内存泄漏。通过猜测编程不起作用。
-
我不认为这是问题。由于要重新分配s.c的先前内容,因此将其删除。当析构函数运行时,它仅删除最后一个,其他删除不应成为问题。
-
@Barmar:除了违反零/三/五规则之外,我看不出还有什么其他办法。关键是意外副本。但是,然后,我们没有所有信息。