1

我在以下代码中检测到 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,引用也会被删除。

4

2 回答 2

6

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

void SomeFunc(Sample x)

创建 的新副本s1。andxs1sptr指向同一个位置。一旦函数SomeFunc返回,内存就会被删除(当 x 被销毁时。)

当主要返回s1被破坏时。现在你的析构函数尝试到一个已经被删除delete的内存位置并且你有错误。double free or corruption


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

Sample(const Sample& s)
{
    ptr = new int(*(s.ptr));
}

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

于 2013-05-05T19:50:34.517 回答
0

对于包含需要在析构函数中释放的资源的任何类,最好为该类创建一个复制构造函数以及一个赋值运算符以避免此类问题。

也就是说,如果您已将SomeFunc函数声明为采用 const 引用,那么一开始就不需要进行复制,这也将更加有效。

void SomeFunc(const Sample &x) {
   ...
}
于 2013-05-05T20:05:58.837 回答