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

问题描述 投票:-1回答:2

我正在使用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;
}

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

c valgrind free calloc
2个回答
0
投票

如果在第一个提示上输入超过16个字符,则对scanf的第一次调用将提取前16个字符,并将所有剩余字符保留在输入缓冲区中。

然后第二个scanf执行时,它需要换行符。下一个字符不是换行符,而是第一个提示中剩余的字符。这将导致不匹配任何内容,因此scanf返回0。这将导致checkInput打印错误消息并调用exit,这将立即退出程序而不释放内存。这是“仍可访问”的内存来自的位置。

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


-1
投票

函数:到达EOF时,checkInput()正在调用exit(),而没有为分配的内存调用free()

建议修改checkInput()以返回int(0表示成功,-1表示失败)并具有main()功能始终检查从checkInput()返回的值并采取相应措施

© www.soinside.com 2019 - 2024. All rights reserved.