17

これは、私の本の 1 つにある質問であり (回答は添付されていません)、私は数日前から考えていました。答えは単純で、反復ごとにガベージ メモリ セルが作成されるため、C++ コードが最終的にクラッシュするということですか?

次の Java および C++ コード フラグメントを検討してください。これは、ユーザー設定を収集し、それらを使用してコマンドとそのパラメーターを組み立てる GUI ベースのアプリケーションの 2 つのバージョンの一部です。メソッド/関数 getUserCommandSpecification() は、コマンド コードとそのパラメーターを表す文字列を返します。返された文字列は、実行される必要なコマンドを構築するために使用されます。

次のことを前提とします。

(i) Command オブジェクト (Java の場合は cmd で参照、C++ の場合は cmd で参照) の while ループでの作成後、生成されたオブジェクトへの参照/ポインター cmd は参照または使用されなくなります。

(ii) アプリケーションは、そのメソッド/関数 execute() とともにクラス Command も定義します。

を。以下に詳述する 2 つのコード バージョンのうち、最終的にクラッシュするのはどれか。
b. プログラムのバージョンがクラッシュするのに、他のバージョンはクラッシュしない理由を説明してください。

Java コード

...
while (true) {
   String commandSpecification = getUserCommandSpecification();
   Command cmd = new Command(commandSpecification);
   cmd.execute();
}
...

C++ コード

...
while (true) {
   string commandSpecification = getUserCommandSpecification();
   Command* cmd = new Command(commandSpecification);
   cmd -> execute();
}
...
4

8 に答える 8

45

はい、C++ バージョンはnew Command(...)with noによりリークしdeleteます。もちろん、それを避けるために別の方法で簡単にコーディングできたはずです。

...
while (true) {
   string commandSpecification = getUserCommandSpecification();
   Command cmd(commandSpecification);
   cmd.execute();
}
...

...その例が彼らが考えているほど有益かどうかはわかりません。

于 2012-11-12T04:24:32.490 に答える
18

C++ コードは、Command決して削除されない無数のオブジェクトを作成しています。C++ にはガベージ コレクションはありません。deleteによって作成されたすべてのインスタンスを呼び出す必要がありますnew

于 2012-11-12T04:24:28.543 に答える
13

生のポインターを使用することはスタイルから外れています。ここでは、すでに指摘したように不要です。実際にポインターが必要な場合は、std::unique_ptr を使用します。

while (true) {
   string commandSpecification = getUserCommandSpecification();
   std::unique_ptr<Command> cmd(new Command(commandSpecification));
   cmd -> execute();
}

ここではメモリリークはありません。

于 2012-11-12T05:45:31.167 に答える
6

C++ の例は、メモリ リークが原因でクラッシュします。

Command* cmd = new Command(commandSpecification);

は、対応する なしで継続的に呼び出されdeleteます。

于 2012-11-12T04:25:14.987 に答える
6

C++ では、ガベージ コレクションはありません (スコープ内のローカルを除く)。したがって、C++ はCommand、 への呼び出しでそのメモリを解放することなく、ヒープにオブジェクトを継続的に割り当てますdelete。したがって、C++ プログラムは最終的にメモリ不足になります。

Java では、ガベージ コレクターはヒープ上のオブジェクトが参照されなくなったことを確認して解放し、メモリ不足エラーを回避します。

于 2012-11-12T04:26:31.480 に答える
4

私の知る限り、C++では作成したオブジェクトを(newキーワードを使用して)明示的に破棄する必要がありますが、Javaではガベージコレクター(到達不能になったオブジェクトによって消費されたメモリを回収するのに役立ちます)がそれを処理します。

Java では、このような方法で作成されたオブジェクトはマイナー GC の頻度を増加させるため、それらのオブジェクトはヒープ内の旧世代領域に到達することさえできない可能性があります (execute実行時間によって異なります)。

Java による卓越したパフォーマンス

于 2012-11-12T04:25:01.417 に答える
1

まだ明示的に言われていないので(ページ内の単語を検索しても一致しません)、追加するのが最善だと思います。C++コードには露骨なメモリリークのバグがあります。

std::auto_ptr(Boostboost::scoped_ptrまたはQtQScopedPointerは代替のスマートポインタです)を使用して、もう1つの実用的な代替手段を次に示します。

while (true) {
   string commandSpecification = getUserCommandSpecification();
   std::auto_ptr<Command> cmd(new Command(commandSpecification));
   cmd->execute();
}
于 2012-11-13T20:56:43.800 に答える
0

Javaでのガベージコレクションについて読んでください。Javaでは、jvmが自動的にオブジェクトを削除するため、手動でオブジェクトを削除する必要はありませんでしたが、C ++では、他に必要のないオブジェクトを削除する必要があります。また、ガベージコレクターは、Javaの強力なツールです。ヘルプが必要な場合は、作業の終了後にオブジェクトをnullに参照できます。

Object x=new Object()
///
.
.
.
you did your works
x=null;
于 2012-11-12T12:15:26.290 に答える