web-dev-qa-db-ja.com

Valgrind:失われた可能性は、間違いなく失われたものとして扱われる可能性がありますか?

Valgrind memcheckの出力、「おそらく失われた」を「完全に失われた」として扱うことはできますか?

失われた可能性がある、または「疑わしい」:ブロックの内部へのポインタが見つかりました。ポインタは元々開始点を指して移動したか、まったく関係がない可能性があります。 Memcheckは、そのようなブロックへのポインタがまだ存在するかどうかが不明であるため、そのようなブロックを「疑わしい」と見なします。

完全に失われた、または「リークされた」:最悪の結果は、ブロックへのポインターが見つからないことです。ブロックへのポインタが存在しないため、プログラマがプログラムの終了時にブロックを解放できなかった可能性があるため、ブロックは「リーク」として分類されます。これは、プログラムの初期の時点でポインタを失ったことの症状である可能性があります

36
webminal.org

はい、私はおそらく失われたと同じくらい深刻な完全に失われたを扱うことをお勧めします。つまり、損失がまったくなくなるまでコードを修正します。

配列を保持しているのと同じポインタを使用して配列をトラバースすると、失われる可能性があります。 あなたインデックスを引くことでポインタをリセットできることを知っています。しかし、valgrindは、それがプログラミングエラーなのか、それともあなたがエラーなのかを判断できません。 賢い これを意図的に行います。それがあなたに警告する理由です。

_#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char** argv) {
  char* s = "string";
  // this will allocate a new array
  char* p = strdup(s);
  // move the pointer into the array
  // we know we can reset the pointer by subtracting
  // but for valgrind the array is now lost
  p += 1;
  // crash the program
  abort();
  // reset the pointer to the beginning of the array
  p -= 1;
  // properly free the memory for the array
  free(p);
  return 0;
}
_

コンパイル

_$ gcc -ggdb foo.c -o foo
_

Valgrindレポート

_$ valgrind ./foo
...
==31539== Process terminating with default action of signal 6 (SIGABRT): dumping core
==31539==    at 0x48BBD7F: raise (in /usr/lib/libc-2.28.so)
==31539==    by 0x48A6671: abort (in /usr/lib/libc-2.28.so)
==31539==    by 0x10917C: main (foo.c:14)
==31539== 
==31539== HEAP SUMMARY:
==31539==     in use at exit: 7 bytes in 1 blocks
==31539==   total heap usage: 1 allocs, 0 frees, 7 bytes allocated
==31539== 
==31539== LEAK SUMMARY:
==31539==    definitely lost: 0 bytes in 0 blocks
==31539==    indirectly lost: 0 bytes in 0 blocks
==31539==      possibly lost: 7 bytes in 1 blocks
==31539==    still reachable: 0 bytes in 0 blocks
==31539==         suppressed: 0 bytes in 0 blocks

...
_

abort()を削除すると、Valgrindはメモリがまったく失われていないことを報告します。中止しないと、ポインタは配列の先頭に戻り、メモリは適切にfreedになります。

これは些細な例です。十分に複雑なコードでは、ポインタがメモリブロックの先頭に戻ることができ、また戻ることはもはや明らかではありません。コードの他の部分を変更すると、おそらく失われる完全に失われるになる可能性があります。だからあなたは気にする必要がありますおそらく失われました

62
lesmana