Valgrind 坚持认为堆上还有内存,但我正在释放指向我拥有的堆的唯一指针

Valgrind insists there's still memory on the heap but I'm freeing the only pointer to the heap I have

我正在使用 Valgrind 查找我的代码中的任何内存泄漏,根据输出,仍有 17 个字节可以访问,1 个分配和 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)

问题是我的代码中只有一个 calloc,我肯定会释放指针:

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;
}

我不确定内存在何处(或如何)泄漏。如果有人可以帮助我找到我的错误或解决问题,我将不胜感激。谢谢

如果您在第一次提示时输入超过 16 个字符,第一次调用 scanf 将选取前 16 个字符,将所有剩余字符留在输入缓冲区中。

然后当第二个 scanf 执行时,它需要一个换行符。下一个字符不是换行符,而是第一个提示符留下的字符。这导致没有任何匹配,所以 scanf returns 0。这导致 checkInput 打印错误消息并调用 exit,它立即退出程序而不释放内存。这就是 "still reachable" 内存的来源。

您需要重组代码,以便所有代码路径 free 分配内存。