Вальгринд: может ли потерянное быть отнесено к потерянным? - PullRequest
33 голосов
/ 21 августа 2010

Могу ли я обработать вывод мемчека Valgrind, «возможно потерянный», как «безусловно потерянный»?

Возможно потеряно или «сомнительно»: указатель на внутреннюю часть блока найден. Первоначально указатель мог указывать на начало и были продвинуты, или это может быть совершенно не связано. Memcheck считает такой блок «сомнительным», потому что неясно, указатель на него все еще существует.

Определенно потеряно или «просочилось»: худший результат - отсутствие указателя на блок. Блок классифицирован как «протекший», потому что программист не мог освободить его в программе выход, так как указатель на него не существует. Это, вероятно, симптом потеряв указатель в какой-то более ранней точке в программе

1 Ответ

61 голосов
/ 21 августа 2010

Да, я рекомендую лечить возможно потерян так же серьезно, как определенно потерян .Другими словами, исправляйте ваш код до тех пор, пока не будет вообще никаких потерь.

Возможно, потеря может произойти, если вы пересекаете массив, используя тот же указатель, который его удерживает. Вы знаете, что вы можете сбросить указатель, вычтя индекс.Но 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 сообщит об отсутствии потери памяти вообще.Без прерывания указатель вернется к началу массива, и память будет free d правильно.

Это тривиальный пример.В достаточно сложном коде больше не очевидно, что указатель может и будет возвращаться к началу блока памяти.Изменения в другой части кода могут привести к тому, что , возможно, потерянный будет , безусловно, потерянным .Вот почему вы должны заботиться о возможно потерян .

...