15

コーディング標準を作成するか、C++ のメモリ管理エラーを排除することが証明できるライブラリを使用することは可能ですか?

Java のようなものを考えています。たとえば、Java アプリケーションでダングリング ポインターを使用することは不可能です。

4

2 に答える 2

0

コーディング標準を作成するか、C++ のメモリ管理エラーを排除することが証明できるライブラリを使用することは可能ですか?

いいえ。

しかし、同じことがJavaにも当てはまります。Java は技術的にはメモリ リークを許可していませんが、注意を怠ると、実際にはメモリ リーク (およびその他のリソース リーク) が発生します。

Android の世界で特によく知られている古典的な例は、リスナーが自分自身を登録解除するのを忘れるため、プログラムの実行時間が長くなるほどリスナー インスタンスのコレクションが増え続ける場合です。これにより、リスナーが大きなグラフィックスへの参照を保持するウィンドウまたはビュー クラスのインスタンスである場合、GUI アプリケーションで数百 MB のリークがすぐに発生する可能性があります。そのすべてのメモリはまだ到達可能であるため、ガベージ コレクションでクリーンアップすることはできません。

技術的にポインターを失っていない (まだコレクション内にある) という事実は、まったく役に立ちません。まったく逆です。ガベージコレクションを妨げているため、リークの原因です。

上記と同じように、Java はダングリング ポインターを技術的に許可していませんが、同様のバグにより、プログラムの有効なメモリ領域にまだ存在しているが、もはや存在しないはずのウィンドウまたはビュー オブジェクトへのポインターにアクセスする可能性があります。見えなくなりました。ポインター アクセス自体がクラッシュや問題を引き起こすことはありませんがNullPointerException、プログラム ロジックが混乱しているため、他の種類のエラーやクラッシュ ( など) がすぐに発生します。


悪いニュースは以上です。

幸いなことに、どちらの言語でも、簡単なガイドラインに従えば、メモリ管理の問題を軽減できます。C++ に関する限り、これは次のことを意味します。

  • 可能な限り標準コレクション (std::vectorや など) を使用してください。std::set
  • ダイナミック アロケーションを 2 番目の選択肢にします。最初の選択肢は、常にローカル オブジェクトを作成することです。
  • ダイナミック アロケーションを使用する必要がある場合は、 を使用しますstd::unique_ptr
  • 他のすべてが失敗した場合は、 を検討してstd::shared_ptrください。
  • 既存の標準コンテナ クラス (や など) はユース ケースで機能しないnewため、低レベルのコンテナ クラスを実装する場合にのみ、ベアを使用してください。ただし、これは非常にまれなケースです。std::vectorstd::set

C++ 用の Boehm ガベージ コレクターもありますが、個人的には使用したことがありません。

于 2017-01-12T16:20:23.703 に答える