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 がある場合とない場合の 2 つの異なる動作があるのはなぜですか?

#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 では、実際には をコピーしません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;
                            }
    };

3 のルールを調べる必要があります。C++ 11 の場合は 5 のルール

于 2013-05-10T15:41:27.300 に答える