我有一个代码,
class foo
{
public:
foo(){};
~foo(){};
};
class bar
{
public:
bar(){};
~bar(){};
foo& Foo()
{
return m_foo;
}
private:
foo m_foo;
};
int main()
{
bar *obj = new bar;
if( /* true condition here */ )
{
foo lcFoo;
lcFoo = obj->Foo(); // forgot this
}
delete obj;
}
现在,当我调用“删除obj”部分时,我从glibc获得了一条双重免费消息。
请建议。
感谢。
编辑: 感谢您的评论,但这是我使用的确切代码。你认为这个问题出在foo& Foo()函数,因为它返回m_foo对象的引用,然后当代码跳转到if条件大括号,那么m_foo将被删除?
答案 0 :(得分:7)
您发布的代码中没有双重免费。我怀疑foo
中有一些指针资源,当复制foo时,它被复制为指针;但在delete
的析构函数中是foo
d。
您可能还想将if
块的内容更改为
foo& lcFoo = obj->Foo();
虽然你在这里获得双重释放的事实表明问题比这更大。
答案 1 :(得分:4)
您的foo
类没有正确实现Rule of Three:每次实现析构函数时,通常都表明您还需要复制构造函数和复制赋值操作
我的猜测是你在foo
类中有一些指针delete
在foo
的析构函数中,但是因为你没有实现一个副本复制foo
类时的构造函数,它只是复制指针。当foo
的两个实例都被破坏时,它们都会尝试free
该指针,并获得错误。
但是,我建议您不要实现复制构造函数和复制赋值运算符,而是在foo
中删除析构函数并使用智能指针(可能是shared_ptr
)。
正如其他人已经指出的那样,你可能也想说foo &lcFoo = obj->Foo()
但只会隐藏更大的问题。
答案 2 :(得分:1)
如果您使用的是Linux,请尝试通过Valgrind运行代码。