15

valgrind で「確実に失われた」バイト数が 1K を超えていない Qt GUI アプリを作成できませんでした。私はこれを実験して、QMainWindow を拡張する QWidget を 1 つだけ表示する最小限のアプリを作成しました。QApplication オブジェクトを表示せずに、または実行せずに、またはその両方を作成するだけですが、常にリークします。

これを理解しようとして、X11またはglibcにバグがあるため、またはvalgrindが誤検知を与えるためであると読みました。また、あるフォーラム スレッドでは、チュートリアルで行われているように、メイン関数で QApplication オブジェクトを作成し、オブジェクトの exec() 関数を返すことは、GUI を作成するための「単純化された」方法であることが暗示されているようです (必ずしも良い方法ではありません)。 、 多分?)。

valgrind の出力では、実際に libX11 と libglibc、さらに libfontconfig について言及されています。残りのメモリ損失である 5 つの損失レコードは、 の??? in libQtCore.so間に発生しQLibrary::setFileNameAndVersionます。

このようなことが起こらないようにする GUI アプリを作成するためのより適切な方法があるとすれば、それは何ですか? また、valgrind の出力のいずれかが単なるノイズである場合、正しいものを抑制する抑制ファイルを作成するにはどうすればよいでしょうか?

編集:コメントと回答ありがとうございます!
失われた数 kB 自体については心配していませんが、エラーの複数の画面をフィルター処理する必要がなく、通常は valgrind から「OK」を取得できる場合は、自分のメモリ リークを簡単に見つけることができます。そして、警告を抑制するつもりなら、それが何であるかを知っておくべきですよね?
リークがどのように受け入れられるかを見るのは興味深いことです!

4

2 に答える 2

20

QT、wxWidgets、X11 などの大規模なマルチスレッド対応ライブラリでは、プロセスの開始時に一度初期化され、その後はクリーンアップを試みないシングルトン タイプのオブジェクトをセットアップすることは珍しくありません。プロセスがシャットダウンしたときの割り当て。

機能から「漏れた」ものはすべてQLibrary::setFileNameAndVersion()、意図的に残されていることを保証できます。X11/glibc/fontConfig によって残されたメモリのビットもおそらくバグではありません。

コーディングの習慣やマナーが悪いと思われるかもしれませんが、特定の種類のタスクを大幅に簡素化することもできます。最近のオペレーティング システムは、プロセスが (適切にまたは強制的に) 強制終了されたときにプロセスによって開かれたままになっているメモリまたはリソースをクリーンアップするための非常に強力な保証を提供し、問題の割り当てがアプリケーションの実行中に必要になる可能性が非常に高い場合、シャットダウン手順を含む-そしてQTのさまざまなコアコンポーネントが適格です-その後、ライブラリがロード/初期化されるとすぐにいくつかのメモリ割り当てを設定し、それらを無期限に保持できるようにすることで、パフォーマンスが向上します。特に、これにより、そのメモリを参照する可能性のある他のすべての C++ デストラクタで使用できるように、メモリを存在させることができます。

これらの割り当てはコード内の 1 点から 1 回だけ設定されるため、意味のある メモリ リークのリスクはありません。プロセスに属しているため、オペレーティングシステムによってプロセスが閉じられるとクリーンアップされるメモリだけです。

結論: メモリ リークがコード内になく、時間の経過とともに大幅に大きくなっていないように見える場合 (そして、最近ではメガバイト単位と考えてください)、および/または明らかに最初の初期化セットアップ コードから発生している場合はアプリ内で 1 回だけ呼び出されるので、心配する必要はありません。おそらく意図的なものです。

于 2012-12-28T18:22:08.780 に答える
0

これをテストする 1 つの方法は、コードをループ内で実行し、反復回数を変えることです。allocs と frees の違いが反復回数に依存しない場合、安全である可能性が高くなります。

于 2016-05-16T10:16:35.337 に答える