Valgrindは、私のコードで次のリークの概要を示しています。ただし、mallocされたすべてのメモリを解放しました。これは悪いことですか、それとも正常ですか?私のプログラムはcにあります。
== 3513 ==リークの概要:
== 3513 ==間違いなく失われました:0ブロックで0バイト。
== 3513 ==失われる可能性があります:0ブロックで0バイト。
== 3513 ==まだ到達可能:1ブロックで568バイト。
== 3513 ==抑制:0ブロックで0バイト。
Valgrindは、私のコードで次のリークの概要を示しています。ただし、mallocされたすべてのメモリを解放しました。これは悪いことですか、それとも正常ですか?私のプログラムはcにあります。
== 3513 ==リークの概要:
== 3513 ==間違いなく失われました:0ブロックで0バイト。
== 3513 ==失われる可能性があります:0ブロックで0バイト。
== 3513 ==まだ到達可能:1ブロックで568バイト。
== 3513 ==抑制:0ブロックで0バイト。
valgrindメッセージstill reachable: 568 bytes in 1 blocks.
は、アプリケーションで解放されたメモリがまだ「到達可能」であることを意味します。これは、どこかにまだメモリへのポインタがあることを意味します。シャットダウン時に、これはおそらくある種のグローバル変数を意味します。ただし、「確実にリークされた」または「おそらくリークされた」バイト数はゼロであるため、この状態は完全に無害です。ご心配なく。
まだ到達可能なメモリとは、グローバルポインタまたは静的ポインタによってポイントされていることを意味します。あなたがしたい--show-reachable=yes
のは、それが問題であるかどうかを確認するためにvalgrindを実行することです。
多くの場合、それは無害であり、次のような関数から発生します。
void foo()
{
static char *buffer = 0;
if (buffer == 0)
{
buffer = (char *)malloc(...);
}
}
そのmallocは引き続き到達可能です。ただし、fooが何度呼び出されても、バッファを1回だけ割り当てるので、ここでバッファを解放しなくても問題はありません。
しかし、次のような関数を考えてみましょう。
void foo()
{
static node_t *head = 0;
node_t *node = (node_t *)malloc(sizeof(node_t));
if (node)
{
node->next = head;
head = node;
}
...
}
この関数が呼び出されるたびに、別のノードが割り当てられます。テスト実行では数ノードしかリークしない可能性がありますが、本番実行では、メモリが不足するほどリークする可能性があります。
違いを判断する1つの方法は、異なる実行で常に同じメモリがリークするのか、より多くのメモリがリークするのかを確認することです。これは、より大きな入力を使用したテスト実行です。
しかし、繰り返しになりますが、安全を確保したい場合は、--show-reachable=yes
何が起こっているかを使用して確認してください。
これらはリークされておらず、心配する必要はありません。メモリはおそらくCライブラリによって割り当てられました。それらがどこに割り当てられたかを本当に知りたい場合は、を実行して--leak-check=full --show-reachable=yes
ください。
free()されたポインタをゼロにすることをお勧めします。これにより、(誤って)それらを再度逆参照しようとするとクラッシュが発生します。
「mallocされたすべてのメモリを解放した」と確信している場合は、問題はありません。多くの場合、コンポーネントを回避する必要がある場合でも、他のパーティからのコンポーネントのメモリリークについては直接責任を負いません。
valgrindからのレポートは、私たちがあなたを助けるのに十分な情報を実際に提供していません。
メモリチェックツールが誤検知を何度も思い付くのを見てきましたが、valgrind自体を直接経験したことはありません。
それはあなたにブロックのアドレスを与えますか?これらの568バイトに含まれるデータの種類を調べることで、多くのことを学ぶことができる場合があります。
うーん、568バイト、これはMAX_PATHユニコード文字列のサイズとほぼ同じです。
個人的には、私は常に忘れてチェックし続けvalgrind make test
ています。これにより、まだ到達可能なバイトが少なくとも2つ追加されます...アプリケーションがvalgrindによって直接実行されていることを確認してください... :)