4

このコードは私が書いたものではありません! クラス WebServer では、+=operator をオーバーロードします。このクラスは、動的に割り当てられた、WebPage *wp; として定義された WebPage (別のクラス、コンポジション) 型のオブジェクトの配列を使用します。

WebServer & operator +=( WebPage webPage ) {
WebPage * tmp = new WebPage [ count + 1];
for (int i = 0; i < count ; i ++)
tmp [i] = wp[i];
tmp [ count ++] = webPage ;
delete [] wp;
wp = tmp;
return * this ;
}

そのため、動的に割り当てられた WebPages の新しい配列を作成し、1 つのオブジェクト用に余分なスペースを確保します。次に、それらに wp が保持する値を割り当て、次に配列に追加したいオブジェクトを割り当てます。したがってdelete[] wp;、プログラムを削除しても問題なく動作します。では、そのコード行を削除するとどうなるでしょうか? また、wp = tmp、それはどういう意味ですか? wp はその動的な新しい名前にすぎないため、クラス内の名前に適していますが、メモリ内の場所は同じですか? または?

4

6 に答える 6

7

したがって、delete[] wp; を削除すると、プログラムはまだ正常に動作します。では、そのコード行を削除するとどうなるでしょうか?

メモリ リークが発生しました。このオペレーターが呼び出されるたびに、プロセスは、最終的にメモリーが不足するまで、そのアドレス空間の一部を浪費します。

またwp=tmp、それはどういう意味ですか? wp はその動的な新しい名前にすぎないため、クラス内の名前に適していますが、メモリ内の場所は同じですか? または?

wpおそらく、それが提供するオブジェクトWebServerのインスタンスを保持する のメンバー (インスタンス変数) です。WebPageしたがって、その行は以前の Web ページの配列を新しい値 (サーバーに追加されたばかりの Web ページを含む) に置き換えています。

WebServer内部の値を読み取り、それらを処理する他のメンバー関数があるwpと思われます。

一般的な注意事項として、このコードは非常に悪い書き方であることに注意してください。なぜなら、リモートでさえ例外セーフではないためです。かなりスマートな実装で回避できる作業を行っており、何よりも、標準言語の代わりに自作コードを使用しています。施設様std::vector

于 2013-08-28T11:30:53.080 に答える
5

次のいずれかを取得します。

  • ただのメモリリークか
  • クラスのデストラクタに副作用のあるコードがあるかどうかに応じて、未定義の動作を伴うメモリ リーク。

この場合、メモリ リークが発生するだけです。ただし、同じ未割り当てメモリが他のオブジェクトに再利用されるかどうかによっては、未定義の動作になる可能性があります。

C++11 標準: [basic.life] (3.8 オブジェクトの有効期間)、パラ 4:

プログラムは、オブジェクトが占有するストレージを再利用するか、非自明なデストラクタを使用してクラス型のオブジェクトのデストラクタを明示的に呼び出すことにより、任意のオブジェクトの有効期間を終了できます。自明でないデストラクタを持つクラス型のオブジェクトの場合、プログラムは、オブジェクトが占有するストレージが再利用または解放される前に、デストラクタを明示的に呼び出す必要はありません。ただし、デストラクタへの明示的な呼び出しがない場合、またはストレージを解放するために削除式 (5.3.5) が使用されていない場合、デストラクタは暗黙的に呼び出されてはならず、デストラクタによって生成される副作用に依存するすべてのプログラムは、未定義の動作があります。

于 2013-08-28T11:31:07.013 に答える
2

何かを削除しないと、メモリ リークが発生します。メモリリークは、壊れたコードの「かなりの時間動作し続けるが、その後失敗する」カテゴリに含まれます。問題は元のエラーからかなり時間がたってから発生し、メモリがどこでどのようにリークしたかを特定するのが難しいことが多く、メモリがなくなると「ランダムな」場所でアプリケーションが失敗するため、対処が難しくなります。利用可能。

また、アプリケーションがメモリ リークを起こすと、他のアプリケーションにとっても問題になります。これは、他のアプリケーションが使用できるメモリが少なくなるためです。

リークの規模によっては、アプリケーションの信頼性が低くなる原因の 1 つになることもあれば (「2 日後にクラッシュする」)、アプリの致命的な原因になることもあります (「実行しない」)。もう少し複雑なユースケースを試したときはうまくいきませんでした」)。または、2 年間連続して使用した後、アプリケーションのメモリ使用量が 64MB から 72MB に増加しただけかもしれません。これは、リークが非常に小さいため、全体のスキームでは実際には気付かないためです。

しかし、メモリ リークが発生することは決して良いことではなく、多くの場合、非常に悪いことです。

于 2013-08-28T11:39:33.673 に答える
0

それは悪いコードかもしれませんが、文字列とベクトルを使用する方法がわかりません (なぜ彼らが私たちに教えてくれなかったのか idk) が、私はまだよく理解していません. それは、最初にWebPage * tmp = new WebPage [ count + 1];新しいスペースを占有し、データを転送してから wp を削除するということですか。それで、何をしwp = tmp;ますか。クラス内の名前に対応するように tmp が占有するスペースに wp という名前を付けるだけですか?しかし、それらのオブジェクトのアドレスは tmp が使用したものと同じですが、削除される前に wp が使用したものとは異なります? ここに画像の説明を入力 何かのようなもの:

于 2013-08-29T09:55:51.977 に答える
0

で割り当てられたオブジェクトnewは、で割り当てが解除されるまでヒープに留まりますdelete。それらを削除しないと、オペレーティングシステムがそれらの割り当てを解除するプロセスが終了するまで、それらはそこに残ります(ただし、アクセスできなくなります->これはメモリリークと呼ばれます)。

于 2013-08-28T11:32:01.483 に答える