Валгринд настаивает на том, что в куче все еще есть память, но я освобождаю единственный указатель на кучу, которая у меня есть - PullRequest
0 голосов
/ 24 марта 2020

Я использую Valgrind для обнаружения любых утечек памяти в моем коде, и согласно выводу, есть еще 17 байтов, которые еще доступны, 1 освобождает c и 0 освобождает:

==9413== 
==9413== HEAP SUMMARY:
==9413==     in use at exit: 17 bytes in 1 blocks
==9413==   total heap usage: 1 allocs, 0 frees, 17 bytes allocated
==9413== 
==9413== 17 bytes in 1 blocks are still reachable in loss record 1 of 1
==9413==    at 0x402C109: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==9413==    by 0x80485F6: main (question3.c:21)
==9413== 
==9413== LEAK SUMMARY:
==9413==    definitely lost: 0 bytes in 0 blocks
==9413==    indirectly lost: 0 bytes in 0 blocks
==9413==      possibly lost: 0 bytes in 0 blocks
==9413==    still reachable: 17 bytes in 1 blocks
==9413==         suppressed: 0 bytes in 0 blocks
==9413== 
==9413== For counts of detected and suppressed errors, rerun with: -v
==9413== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Дело в том, что в моем коде есть только один callo c, и я определенно освобождаю указатель:

void checkInput(int err) {
  if (!err || err == EOF) {
    printf("\nInvalid input!\n");
    exit(1);
  }
}

#define N 17
int main() {
  char bufferStack[N] = { 'a' };
  char * bufferHeap = calloc(N, sizeof(char));
  char junk[N];
  printf("Enter a string no more than 16 chars long\n0123456789012345\n");
  checkInput(scanf("%16[^\n]", bufferStack));
  printf("BufferStack: %s\n", bufferStack);
  checkInput(scanf("%16[\n]", junk));
  checkInput(scanf("%16[^\n]", bufferHeap));
  printf("BufferHeap: %s\n", bufferHeap);
  free(bufferHeap);
  return 0;
}

Я не уверен, где (или, скорее, как) утечка памяти. Если кто-то может помочь мне найти мою ошибку или решить проблему, я действительно ценю это. Спасибо.

1 Ответ

2 голосов
/ 24 марта 2020

Если вы введете более 16 символов в первом запросе, первый вызов scanf заберет первые 16 символов, оставив все оставшиеся символы в буфере ввода.

Затем, когда исполняется второй scanf, он ожидает символа новой строки. Следующий символ - это не новая строка, а символ, оставшийся после первого запроса. Это приводит к тому, что ничего не найдено, поэтому scanf возвращает 0. Это приводит к тому, что checkInput выводит сообщение об ошибке и вызывает exit, который немедленно выходит из программы без освобождения памяти. Вот откуда исходит «все еще достижимая» память.

Вам нужно будет реструктурировать свой код так, чтобы все пути кода free выделяли память.

...