为什么即使在复制对象时也会检测到双重释放或损坏

时间:2013-05-05 19:46:36

标签: c++

我在以下代码中检测到glibc,有人可以向我解释

#include<iostream>
using namespace std;
class Sample
{
public:
       int *ptr;
       Sample(int i)
       {
           ptr = new int(i);
       }
       void PrintVal()
       {
       cout << "The value is " << *ptr<<endl;
       }
       ~Sample()
       {
           cout<<"CALLED\n";
            delete ptr;
       }
};
void SomeFunc(Sample x)
{
    cout << "Say i am in someFunc " << endl;
    x.PrintVal();
    //cout<<*(s1.ptr)<<endl;
}
int main()
{
Sample s1=10;
cout<<*(s1.ptr)<<endl;
SomeFunc(s1);
cout<<"HERE\n";
cout<<*(s1.ptr)<<endl;
}

在调用cout<<*(s1.ptr)<<endl;时,检测到glib。我无法理解的是,即使没有为s1调用desructor,引用也会被删除。

2 个答案:

答案 0 :(得分:6)

问题在于您没有复制构造函数,并且您拥有动态分配的成员数据。

void SomeFunc(Sample x)

创建s1的新副本。 xs1的{​​{1}}将指向同一位置。一旦函数ptr返回该内存被删除(当x被销毁。)

当主要回归SomeFunc被销毁时。现在,您的析构函数尝试s1 已删除的内存位置,并且您出现delete错误。


您案例的简单复制构造函数

double free or corruption

你似乎并没有在这里使用指针和动态分配。但是,如果您必须使用动态分配,请考虑查看Rule of threesmart pointers

答案 1 :(得分:0)

对于包含需要在析构函数中释放的资源的任何类,最佳做法是为该类创建一个复制构造函数以及一个赋值运算符,以避免出现类似这样的问题。

也就是说,如果你已经宣布 SomeFunc 函数采用const引用,那么首先就不需要复制,这也会更有效。

void SomeFunc(const Sample &x) {
   ...
}