int
次のように、オブジェクトのメモリ位置を動的に割り当てた場合:
int *x = new int;
それが終わったら、ヒープ上のメモリを解放したいので、次のようにします。
delete x;
今、私が次のことをしなかった場合:
x = NULL;
別のアドレスx
を指していますか?更新:代わりに another
many
私がしなかったと言って、別のx = NULL
を作った場合、どうなりますか? delete x;
int
次のように、オブジェクトのメモリ位置を動的に割り当てた場合:
int *x = new int;
それが終わったら、ヒープ上のメモリを解放したいので、次のようにします。
delete x;
今、私が次のことをしなかった場合:
x = NULL;
別のアドレスx
を指していますか?更新:代わりに another
many
私がしなかったと言って、別のx = NULL
を作った場合、どうなりますか? delete x;
x
。= NULL
注: 一部のランタイム システムは、二重削除の特定の非常に単純なケースからユーザーを保護します。詳細によっては、これらのシステムのいずれかで実行していて、処理が異なる別のシステムにコードをデプロイする人がいない場合や、デストラクタを持たないものを削除している場合や、 2 つの削除の間に重要なことは何もしません。また、2 つの削除の間に重要なことを行うためにコードを変更する人が誰もいない場合、およびスレッド スケジューラ (制御できない可能性があります!) がたまたまスレッドをスワップしない場合2 つの削除と if、および if、および if。マーフィーの話に戻りますが、失敗する可能性があるため、最悪の場合に失敗します。
の後、delete
ポインタには通常、(現在は空いている)メモリのアドレスが含まれています。2つ目delete
は未定義の動作を与えるので、そうしないでください。
未定義の動作を呼び出します。そうしないと、無効なメモリ位置を指していることになり、使用しようとすると未定義の動作が発生しますx=NULL
。x
タイプ:
int main(){
int* i = new int;
std::cout << i << std::endl;
delete i;
std::cout << i << std::endl;
delete i;
}
結果:
0x8e19008
0x8e19008
**glibcが検出されました**./a.out:ダブルフリーまたは破損(ファストトップ):0x08e19008 *
ご覧のとおり、アドレスは同じままですが、2回目の削除はランタイムエラーで終了します。動作は詳細には環境によって異なりますが、原則として機能しません。
すでに削除されたメモリでdeleteを呼び出すと、未定義の動作が発生します。通常、プログラムはクラッシュします。
xを削除した後、それが指す場所は「コンパイラに依存」します。ほとんどのコンパイラは、deleteが呼び出される前に、それがどこにあったかを指すようにします。ただし、そのメモリアドレスは無効であるため、呼び出さないでください。
これと同じ理由で、「これを削除する」は、必要に応じて、非常に慎重かつ慎重に使用する必要があります。:-)
2 番目の削除は未定義です。
補足として、二重削除を検出するツールがあります。最高のものの1つはValgrindです。