技術共有

deleteとdelete[]の混在による未定義の問題についての説明

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

delete は動的空間を解放するために使用され、delete[] は複数の動的空間を解放するために使用されることはわかっていますが、これらを混在させるとどのような問題が発生するでしょうか?ブログの多くの記事を読みましたが、満足のいくものではなかったので、その内容とその理由をお知らせするためにこの記事を書きました(表面的な説明です、修正してください)。

---------------------------------------------------------------------------------------------------------------------------------

まず例を見てみましょう。

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

ただし、デストラクターを明示的に記述しない場合は、次のようになります。

結果は正常に動作します。

---------------------------------------------------------------------------------------------------------------------------------

なぜ?

システムがこれら 10 個のクラス A オブジェクトに割り当てるスペースの量を尋ねると、おそらく 40 バイトと答えるでしょう。1 つの A は 4 バイト、10 は 40 バイトです。 。しかし、実際には、デストラクタを自分で作成すると、合計 44 バイトが割り当てられます。デストラクタを作成しなかった場合は、合計 40 バイトが割り当てられます。

デストラクターを書き込んだ後、さらに 4 バイトが存在するのはなぜですか? delete を使用してこのスペースを解放した後、デストラクターが自動的に呼び出されることがわかっています (http://t.csdnimg.cn/f2FOj)、(1) デストラクターを自分で作成した場合、delete はそれを呼び出す必要があります (実際、delete も関数であり、関数のネストされた呼び出しと同等です。) の場合、何回呼び出されるかが問題になります。これらの 4 バイトはまさに整数のサイズであり、この整数はこの空間内のオブジェクトの数を記録するために使用され、それによってコンストラクターとデストラクターが何回呼び出される必要があるかを決定します。と呼ばれた。ただし、p ポインタはまだ最初のオブジェクトを指していますが、構築および破棄中にオブジェクトの数を取得するために先に進むことを知っておく必要があります。、具体的な関係は次のとおりです。

(2) この時点でデストラクターを作成しない場合、回数を記録せずにコンパイラーによって生成されたデストラクターが呼び出されます (より低いレベルが関係する可能性があります。よくわかりません。修正してください)。追加の整形外科を開く必要はありません。

さて、上の例を説明しましょう

デフォルトでは、Delete はポインタが指す位置からスペースを解放します。delete[] はまず、デフォルトでさらにスペースが開いているかどうかを確認し、開いている場合は、ポインタを 1 つ前に移動してから解放します。さらにスペースを開くか、削除を使用してスペースを解放すると、開いたスペースを解放できず、メモリ リークが発生するため、エラーが報告されます。

これを実践するとエラーが発生しますか? :

デストラクタを呼び出す必要がなく、オブジェクトの数をカウントする必要がなく、さらにスペースを空ける必要がないため、ポインタが指す位置からスペースを解放することができ、エラーは発生しません。報告。

多くの状況があるので、自分で試してみることができます。

表現力が足りないので、何度か読んでいただければ必ず何かを得られます。