0

当我覆盖复制构造函数时,为什么它会在第一次删除自身时出现段错误。输出:

$./a.out
inside ctor
inside copy-ctor
Say i am in someFunc
inside dtor
*** glibc detected *** ./a.out: free(): invalid pointer: 0xb75f3000 ***

如果我不覆盖 copy-ctor,那么我可以看到它s1.PrintVal()被调用,然后 *ptr 中出现了预期的段错误。

为什么有和没有默认和覆盖的复制ctor有两种不同的行为?

#include<iostream>
using namespace std;
class Sample
{
public:
    int *ptr;
    Sample(int i)
    {
        cout << "inside ctor" << endl;
        ptr = new int(i);
    }
    Sample(const Sample &rhs)
    {
        cout << "inside copy-ctor" << endl;
    }
    ~Sample()
    {
        cout << "inside dtor" << endl;
        delete ptr;
    }
    void PrintVal()
    {
        cout <<" inside PrintVal()."<<endl;
        cout << "The value is " << *ptr<<endl;
    }
};
void SomeFunc(Sample x)
{
    cout << "Say i am in someFunc " << endl;
}

int main()
{
    Sample s1= 10;
    SomeFunc(s1);
    s1.PrintVal();
    return 0;
}
4

2 回答 2

3

在您的 copy-ctor 中,您实际上并没有 copy ptr,这意味着它的值将是未指定的,并且您将删除一个未指定的指针(而不是像使用默认的 copy-ctor 那样双重删除普通指针)。

于 2013-05-10T15:34:29.213 回答
0

默认复制 ctor 按值复制每个成员。这将为指针创建一个别名,因此每个类在调用其 dtor 时都会删除指针并导致错误。

在几乎所有你有一个正在分配的指针的类中,你都需要编写一个自定义复制构造函数来分配指针,然后复制值。

class Sample
    {
            public:
                            int *ptr;
                            Sample(int i)
                            {
                                    cout << "inside ctor" << endl;
                                    ptr = new int(i);
                            }
                            Sample(const Sample &rhs)
                            {
                                    ptr = new int(*rhs.ptr);
                            }
                            Sample & operator=(const Sample& other)
                            {
                                // You should also override copy assignment if you overide copy 
                                // you don't need to allocate in this case just copy the value 
                                *ptr = *other.ptr;
                            }
                            ~Sample()
                            {
                                    cout << "inside dtor" << endl;
                                    delete ptr;
                            }
                            void PrintVal()
                            {
                                    cout <<" inside PrintVal()."<<endl;
                                    cout << "The value is " << *ptr<<endl;
                            }
    };

您应该查找三规则,如果您在 c++ 11 中查找五规则

于 2013-05-10T15:41:27.300 回答