4

私は C と Java のプログラマーなので、メモリ割り当てと OOP は私にとって目新しいものではありません。しかし、オブジェクトの C++ 実装でメモリ リークを正確に回避する方法についてはわかりません。すなわち:

string s1("0123456789");
string s2 = s1.substr(0,3);

s2新しい文字列オブジェクトがあるため、次の方法で解放する必要があります。

delete &s2;

右?

さらに、戻り値の型がポインターまたは参照ではないにもかかわらず、関数によって返される (新しい) オブジェクトのアドレスを削除する必要があると仮定するのは正しいですか? ヒープ上に存在するオブジェクトを解放する必要があるときにポインターとして返されないのは奇妙に思えます。

4

8 に答える 8

16

いいえ。

割り当てたメモリを解放するだけで済みます (つまり、new または memalloc を介して)。

于 2009-06-28T21:05:01.297 に答える
12

いいえ、

s1範囲外になると、と の両方s2が破棄されます。

s1.substr()考える必要のない一時的なオブジェクトを作成します。

于 2009-06-28T21:01:33.723 に答える
5

s1 と s2 の両方が自動割り当てされます。あなたはそれらを削除しません。deleteを使用して作成したオブジェクトのみを使用しnewます。

C++ は、auto、static、dynamic の 3 つの割り当てモードを認識しています。それらについて読んでください。例の文字列のような自動値は、スコープを離れると自動的に解放されます。それらのデストラクタは自動的に呼び出されます。文字列が操作中に動的に割り当てたメモリは、文字列デストラクタが呼び出されると解放されます。

于 2009-06-28T21:04:02.750 に答える
1

現代のC++(特にACバックグラウンドから来ている)で理解するための最も重要な概念の1つは、RAIIです。C ++は、メモリ(またはミューテックス、トランザクション)などのリソースをクラス内にカプセル化します。クラスは構築時にリソースを「取得」し(文字列コンストラクターは動的メモリを割り当てます)、破棄時にリソースを「解放」します(文字列クラスを破棄すると解放されます)。スタックオブジェクトの破棄は決定論的であるため(囲まれたスコープが期限切れになるとスタックベースのオブジェクトは期限切れになります)、リリースを書き込む必要はなく、例外がスローされた場合でも発生します。

だから、いや。私のコーディングのほとんどでは、リソースが文字列、STL conatiner、またはshared_ptrまたはscoped_ptrによって管理されているため、明示的な削除(またはdelete [])を書き込むことはありません。

于 2009-06-28T21:21:57.083 に答える
1

なぜs2を手動で解放する必要があるのですか? s2 の動的メモリの削除は、std::string デストラクタによって処理されます。

于 2009-06-28T21:01:52.270 に答える
1

いいえ、s2手動で削除する必要はありません。これはスタック上のローカル変数であり、宣言時に自動的に割り当てられたように、スコープ外になると自動的に破棄されます。通常delete、あなたが割り当てたものだけですnew

関数によって返された一時オブジェクトは自動的に管理され、ステートメントの終わりまでに破棄されます - それらがより長く必要な場合は、通常、一時オブジェクトが破棄される前にローカル変数にコピーされます (たとえば、次Object o = f();の行のような単純な代入によって)substr()あなたの例で呼び出します)。

関数がポインターを返す場合、ポイント先のオブジェクトはこのように自動的に管理されません。すべての作業が完了したら、誰がオブジェクトを削除する責任があるかをドキュメントに記載する必要があります。デフォルトの規則として、通常、オブジェクトを割り当てた人が再度削除する責任がありますが、詳細はどこかに文書化する必要があります。

于 2009-06-28T21:03:16.730 に答える