私の質問は一部の人にとっては些細なことに思えるかもしれませんが、なぜこのコードが理解できません:
double * a = new double [3];
a[0] = 1;
a[1] = 2;
a[2] = 3;
a = 0;
for(int i=0; i<3;i++)
cout << " a[" << i << "] = " << a[i] << endl;
delete [] a ;
次の結果は得られません。
a[0] = 0;
a[1] = 0;
a[2] = 0;
私の質問は一部の人にとっては些細なことに思えるかもしれませんが、なぜこのコードが理解できません:
double * a = new double [3];
a[0] = 1;
a[1] = 2;
a[2] = 3;
a = 0;
for(int i=0; i<3;i++)
cout << " a[" << i << "] = " << a[i] << endl;
delete [] a ;
次の結果は得られません。
a[0] = 0;
a[1] = 0;
a[2] = 0;
で割り当てられた元のメモリnew[]
がリークしています。あなたは今、同等のものを持っています
double * a = 0; //or NULL
メモリリークあり。null ポインターにアクセスすると、未定義の動作が発生します。いいえ、ポインタへの代入0
はメモリを破壊しません。
コードがクラッシュしたり、ランダムな結果が生成されたりします (他の定数を に割り当てた場合a
)。なんで?
あなたのコードでa
は、あなた自身の使用のために(を使用して)主張しているメモリのいくつかの領域へのポインタですnew
。したがって、a
likeの値があります0x05237484
(単なるランダムな例です)。0x05237484
したがって、そのアドレスによって24 バイト (3*8、8 は double のサイズ) のバイトが予約されていることがわかります。基本的に、あなたが と言うとき、new double[5]
あなたがランタイムに言っているのは、「今、5 つの double の配列を格納するのに十分なスペースを見つけて、それを私のために予約して、私だけがそれを使用できるようにする」ということです。ランタイムはメモリを予約し、指定したポインタにアドレスを格納します -a
次に、ポインターa
を他の値で上書きします。delete
これは、メモリがまだ予約されていることを意味します (またはを使用して、もはや必要ではないことをランタイムに伝えていないため) が、メモリがdelete[]
どこに保存されているかを忘れています。
代わりに、レコードは別のメモリの場所を指すようになりました。ここには何でもあります。したがって、現在指している場所からランダムな値を取得するか (同じプロセスメモリ内で終了した場合)、プログラムが「アクセス違反」と言ってクラッシュします。つまり、に属するメモリにアクセスしようとしたことを意味します。別のプロセス/システム/何でも。割り当て後にここで行っていることは、 a = 0
3 つの場所にアクセスすることです。
a[0] // which is a+0 == 0x00000000
a[1] // which is a+1 == 0x00000001
a[2] // which is a+2 == 0x00000002
その場所に何があるかはわかりませんが、試してみると、「アクセスが拒否されました」というエラーが発生するか、(アプリケーションの他の部分に属する) ランダムなデータを受け取ることになります。
さらに悪いことに、あなたはいくらかのメモリを手に入れましたが、それを解放しませんでした。これは、コンピュータの RAM を無駄に使い果たしたことを意味します。それが「メモリリーク」と呼ばれるものです
ポインターにゼロを割り当てても、割り当てられたメモリは破棄されません。そのポインターは、そのメモリ セグメントを指すように停止します。ゼロを割り当てた後delete[]
、メモリのその部分は削除されません。