0

_ _ _以下のプログラムは、「deletep」および「p = NULL」の後にMyClass::processingが呼び出されるとクラッシュするはずですが、「MyClass::a」にアクセスしようとするとクラッシュします。なぜそうなのか???

#include <iostream>
using namespace std;

class MyClass
{
public:
        int a;
        void processing()
        {
                cout<<"Processing"<<endl;
        }
};

int main(void)
{
        MyClass* p(new MyClass);
        MyClass* q = p;
        p->a = 10;
        cout<<"p:: "<<p<<" q:: "<<q<<endl;
        cout<<"p->a"<<p->a<<"q->a"<<q->a<<endl;
        delete p;
        p->processing();   // Watch out! p is now dangling!
        cout<<"\n\nAfter Deletion::"<<endl;
        cout<<"p:: "<<p<<" q:: "<<q<<endl;
        cout<<"p->a"<<p->a<<"q->a"<<q->a<<endl;
        p = NULL;           // p is no longer dangling
        cout<<"\n\nAfter Assigning null"<<endl;
        p->processing();   // Watch out! p is now dangling!
        q->processing();   // Ouch! q is still dangling!
        cout<<"p:: "<<p<<" q:: "<<q<<endl;
}
4

1 に答える 1

0

インスタンスを削除した後にメソッドを呼び出すことは未定義の動作です。なんでも起こる可能性がある。

考えられる動作の例:

  1. あなたは「ラッキー」です:freeメモリを解放しただけで、それを無効にしませんでした。インスタンスは部分的に無傷であり、呼び出しは偶然成功します。
  2. freeガベージ(またはセンチネル値)でメモリを上書きし、クレイジーなアドレスとセグメンテーションフォールトにジャンプします。
  3. freeブロック全体の割り当てを解除し、アクセスしようとするとセグメンテーション違反になります*p
  4. 他のスレッドがsystem、現在使用されていないメモリ ブロックに のアドレスを書き込みます。あなたのスタックにはたまたまへのポインタが含まれています"rm -rf /"。ハードドライブが消去され、陽気さが続きます。

未定義の動作に決して頼らないでください。

于 2013-02-19T07:21:27.427 に答える