2016-07-22 11 views
0

最近私はNCursesを教えていましたが、valgrindでコードをテストしてメモリリークをチェックすることにしました。この小さなコードは私のプログラムと同じエラー結果をもたらし、誰かが間違っていることを知っているのか、それとも私を答えに導くことができるのかを知りたいと思います。NCursesメモリ割り当てvalgrindメッセージ

#include <ncurses.h> 
int main() 
{ 
    initscr(); 
    WINDOW *win = newwin(0,0,10,10); 
    delwin(win); 
    endwin(); 
    return 0; 
} 

== 20986 == Memcheck、メモリエラー検出
== 20986 ==著作権(C)2002から2013、およびGNU GPLに、ジュリアンスワードらによる。
== 20986 == Valgrind-3.10.1とLibVEXを使用する。
== 20986:
== 20986 ==
== 20986 ==
== 20986 == HEAP概要./a.out:著作権情報
== 20986 ==コマンドの-hと再実行==出口で使用さ:193個のブロック
== 20986 ==合計ヒープ使用量の281089バイト:
:248のallocs、55の解放し、353425のバイトが == 20986 ==
== 20986 == LEAK概要
割り当て == 20986 ==確実に失われた:0ブロックの0バイト
== 20986 ==間接的に失われた:0ブロックの0バイト
は== 20986 ==おそらくは失わ:0ブロック内の0バイト
== 20986 ==まだ到達:193個のブロック内281089バイト抑制
== 20986 == 0のブロック0バイト
== 20986 ==を-v
== 20986 == ERROR:--leak-チェック=リークしたメモリ
== 20986 ==
== 20986検出と抑制、エラーのカウントのために==、再放送での詳細を見ることがいっぱいで再実行してください要約:0のコンテキストからの0エラー(抑制:0から0)

ありがとうございました。

+0

いいえ、valgrindは0バイトがリークされたことを示し、281089バイトはまだ割り当てられていますが、明らかにリークされていないことを示しています。正確に何が間違っていますか? – immibis

答えて

1

ライブラリは、多くの場合、あなたのint main()が終了した後に何かを行います。言われていること

、後に何が起こるかの例は以下の通りです:プログラム例で

#7 0x00007ffff72abfe8 in __run_exit_handlers (status=0, 
    listp=0x7ffff76355f8 <__exit_funcs>, 
    [email protected]=true) at exit.c:82 
#8 0x00007ffff72ac035 in __GI_exit (status=<optimized out>) at exit.c:104 
#9 0x00007ffff7292837 in __libc_start_main (
    main=0x429e26 <main(int, char**)>, argc=1, argv=0x7fffffffde28, 
    init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
    stack_end=0x7fffffffde18) at ../csu/libc-start.c:325 
#10 0x0000000000419f69 in _start() 

。上記の出力はGDBによって提供されました。しかし、スタックトレース行#7には関連性があり、listp=0x7ffff76355f8という部分があります。それはatexit();関数に登録された関数コールバックのリストです。おそらくncursesで使われているもの、さらにはstd/stlライブラリのいくつかでさえ、そこにクリーンアップを持つことができます。一般に、または少なくとも私が読んだところでは、呼び出し元のライブラリがそのクリーンアップを管理しているため、valgrindはそれらのリソースフリーでいつも拾うことができません。

+0

GDBのエラーログと説明をありがとう。私は今、なぜバレングローンがそのようなことを言うのかを把握しています。私の質問に答えました。 – AxiosAmneisa

+0

いつでも - ハッピープログラミング。 – M4rc

3

示されたコードに問題はありません。通常、さまざまなランタイム・ライブラリーは、共用ライブラリーがアンロードされたときにそれらの割り振りを解除することなく、実行時に内部バッファー用にメモリーを割り振ります。

+0

そうですか?私はそれを知らなかった。私に答えてくれてありがとう。 – AxiosAmneisa

1

答えはncursesのよくある質問Testing for Memory Leaksである:

おそらく、あなたはメモリリークを確認するために、このようなdmallocまたはvalgrindなどのツールを使用していました。それは通常、まだ使用中の多くのメモリを報告します。それは正常です。

のncurses configureスクリプトは、分析を継続するために使用できるオプション、--disable-leaksを、持っています。可能であれば、ncursesにメモリを解放するよう指示します。ただし、使用中のメモリのほとんどは「永続的」です。

呪いの任意の実装がない無料のスクリーンに関連付けられたメモリは、(たとえendwin()を呼び出した後)ので、refresh()次の呼び出しで使用するために利用可能でなければならない必要があります。パフォーマンス上の理由からメモリチャンクもあります。そのため、cursesアプリケーションのメモリーリークを分析するのは難しくなります。この問題を回避するには、可能なチャンクを解放するncursesライブラリのデバッグバージョンをビルドし、終了時に残りの部分を解放するために_nc_free_and_exit()関数を提供します。 ncursesユーティリティとtest programsは、たとえばExitProgram()マクロを介してこの機能を使用します。

たとえば、Debianは、メモリリークのテストに役立つパッケージを提供しています(libncurses5-dbgおよびlibncursesw5-dbg)。

+0

ありがとうございます。私は、将来そのページとウェブサイトを使用することは間違いありません。 – AxiosAmneisa