0

ソケットサーバーを書きました。そして、実行中にCtrl-Cを押すと、メモリリークの可能性があることに気づきました。これを見つけるためにvalgrindを使用しました。

私のサーバー コードは非常に単純です。基本的に、Listener オブジェクトを作成し、スレッドを開始して接続を受け入れ、そのスレッドに参加しようとします。

 try {
    Server::Listener listener(1234);

    boost::thread l(boost::bind(&Server::Listener::start, &listener));

    l.join();

} catch(exception& e) {
    cout<<e.what()<<endl;
}

valgrind を実行すると、次のようになります。

==3580== Command: bin/Debug/p_rpc
==3580==
Listner started ...
in loop..
^C==3580==
==3580== HEAP SUMMARY:
==3580== 終了時に使用中: 24 ブロックで 3,176 バイト
==3580== 合計ヒープ使用量: 28 の割り当て、4 つの解放、4,328 バイトの割り当て
==3580==
==3580== 1 ブロックで 288 バイトが損失レコードで失われる可能性があります21/24
== 3580== 0x4C29E46: calloc (/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3580== by 0x4012084: _dl_allocate_tls (dl-tls.c:297)
==3580== by 0x4E3AABC: pthread_create@@GLIBC_2.2.5 (allocatestack.c:571)
==3580== by 0x5260F9F: boost::thread::start_thread() (で
/usr/lib/libboost_thread.so.1.49.0) ==3580== by 0x407B93: ブースト::スレッド::スレッド、ブースト::_bi::list1 > > >(ブースト::_bi::bind_t、ブースト: :_bi::list1 > >&&) (thread.hpp:171)
==3580== by 0x404CA4: main (main.cpp:179)
==3580==
==3580== リークの概要:
==3580==確実に失われた: 0 ブロックで 0 バイト
==3580== 間接的に失われた: 0 ブロックで 0 バイト
==3580== 失われた可能性: 1 ブロックで 288 バイト
==3580== まだ到達可能: 23 ブロックで 2,888 バイト
==3580 == 抑制: 0 ブロックに 0 バイト
==3580== 到達可能なブロック (ポインターが見つかったブロック) は表示されません。
==3580== それらを見るには、 --leak-check=full --show-reachable=yes
==3580==で再実行してください。
==3580== 検出され抑制されたエラーの数については、次を使用して再実行します: -v
==3580== エラーの概要: 1 つのコンテキストから 1 つのエラー (抑制: 2 から 2)
強制終了

288バイトが失われる可能性があることを指摘しています。シグナル ハンドラーを使用してこのリソースを解放できると思います。しかし、私はそれを行う方法がわかりません。例を教えてください。

乾杯、エルトン

4

2 に答える 2

2

プロセスが閉じると、OS はプロセスが所有するすべてのメモリを自動的にクリーンアップします。プログラムの終了時にそのメモリを解放することについて心配する必要はありません。建物は解体中です。わざわざ床を掃除したり、ゴミ箱を空にしたり、ホワイトボードを消したりしないでください。また、建物の出口に並ばないでください。全員が磁石を出入りできるようにします。あなたがしているのは、これらの無意味なハウスクリーニング作業が完了するのを解体チームに待たせることだけです。

心配する必要がある種類のリークは、プログラムの有効期間中に継続的にリークするものです

于 2013-01-29T22:52:01.860 に答える
1

原則として、そこでオブジェクトを破壊できます。シグナル ハンドラーでできることには制限があり、それらはスレッドと非常にうまく混ざりません。この領域では、コンパイラはチェックをまったく(またはほとんど) 実行できないことに注意してください。シグナル ハンドラは単なる通常の関数です。特に注意してください。

この質問への回答は、それを行う方法の詳細を提供します。

于 2013-01-29T23:02:08.740 に答える