Подтвердить что ты не робот

Valgrind: возможно, потеряно, как можно потерять?

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

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

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

4b9b3361

Ответ 1

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

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

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