2

次のコードでは:

int main(int argc,char * argv[]){
  int * ptr;
  ptr = 0; // tried also with NULL , nothing changes
  ptr = new int[10]; // allocating 10 integers
  ptr[2] = 5;
  ptr[15] = 15;  // this should cause error (seg fault) - but it doesn't

  cout << ptr[2] << endl;
  cout << ptr[15] << endl;  // no error here

  delete [] ptr;

  cout << ptr[2] << endl;   // prints the value 5
  cout << ptr[15] << endl;  // prints the value 15
}

実行結果は次のとおりです。

5        
15        
5        
15        
  1. インデックス番号が 15 の要素が存在する可能性があるのは、10 個しか割り当てていない場合です。
  2. 配列全体の割り当てが解除された後もポインターに値が残っているのはなぜですか?

次のような単一の割り当てで削除を試みました:

int * ptr;
ptr = 0;
ptr = new int;
*ptr = 5;
cout << *ptr << endl;
delete ptr ;
cout << *ptr << endl;

結果は正常です。

5        
0        

コンパイラに依存しないことを確認するために、fedora 17 および別のプラットフォーム (SLC5 - Red Hat ベースの Linux) で gcc 4.7.2 および gcc 4.1.2 を使用してテストされています。ここで何が間違っていますか?

4

3 に答える 3

9
  1. 配列の意図したサイズを超える要素が存在します。これは、そこにメモリがたまたま存在していたためです。それを使って何かをすることは違法であり、未知の闇につながります。

  2. 割り当て解除とは、メモリが割り当てられなくなったことを意味します。誰かがそこに行って掃除したという意味ではありません。しかし、そこに残っているものにアクセスすることは違法であり、未知の闇につながります。

于 2012-10-07T20:02:25.040 に答える
1

アレイに属していないメモリにアクセスしています。それは純粋な運のために機能します。プログラムがクラッシュしない場合は、自分のアプリケーションに属するメモリの一部を上書きしていることを意味します。そのため、どこかで何かが台無しになり、プログラムが正しく機能することが保証されなくなります。

他のアプリケーションのメモリにアクセスするため、ほとんどの場合、セグメンテーション違反が発生します。今回は、あなたはただ「ラッキー」です。または、私がそれを「不運」と呼ぶように、プログラムにメモリエラーがあることを実行からすぐに知ることができないためです。

于 2012-10-07T20:02:33.030 に答える
1

削除されたポインターの間接参照は、C++標準で定義されている未定義の動作です。そしてそれはまさにそれです-未定義の振る舞い。クラッシュしたり、0を取得したり、以前にあったものを取得したり、42を取得したりする可能性があります。定義上、その時点では「通常の」動作はありません。

于 2012-10-07T20:06:10.860 に答える