为什么Valgrind在calloc语句中显示内存泄漏

6 c gcc valgrind memory-leaks

我正在尝试学习一些事情(作为一种爱好)并试图学习使用Valgrind.然而,这对我来说似乎没有意义.似乎Valgrind说我在使用calloc之前使用calloc分配字节时会丢失字节!有人可以解释这里发生了什么,为什么第二个程序有效?我在Eclipse中以调试模式编译了程序,并在调试可执行文件上运行了Valgrind.

这是程序:

1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 int main(void) {
6
7     char* origstr = calloc(37, sizeof(char*));
8     char* newsubstr = calloc(9, sizeof(char*));
9
10    origstr = "TheQuickBrownFoxJumpedOverTheLazyDog";
11
12    strncpy(newsubstr, origstr + 8, 8);
13    printf("SubString is: %s\n", newsubstr);
14
15    free(newsubstr);
16    free(origstr);
17    return 0;
18 }
Run Code Online (Sandbox Code Playgroud)

以下是Valgrind给我的意思:

$ valgrind --tool=memcheck --leak-check=full ./test
==25404== Memcheck, a memory error detector
==25404== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==25404== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==25404== Command: ./test
==25404== 
SubString is: BrownFox
==25404== Invalid free() / delete / delete[] / realloc()
==25404==    at 0x4C29E90: free (vg_replace_malloc.c:473)
==25404==    by 0x400665: main (test.c:16)
==25404==  Address 0x4006f8 is not stack'd, malloc'd or (recently) free'd
==25404== 
==25404== 
==25404== HEAP SUMMARY:
==25404==     in use at exit: 296 bytes in 1 blocks
==25404==   total heap usage: 2 allocs, 2 frees, 368 bytes allocated
==25404== 
==25404== 296 bytes in 1 blocks are definitely lost in loss record 1 of 1
==25404==    at 0x4C2AD10: calloc (vg_replace_malloc.c:623)
==25404==    by 0x4005FC: main (test.c:7)
==25404== 
==25404== LEAK SUMMARY:
==25404==    definitely lost: 296 bytes in 1 blocks
==25404==    indirectly lost: 0 bytes in 0 blocks
==25404==      possibly lost: 0 bytes in 0 blocks
==25404==    still reachable: 0 bytes in 0 blocks
==25404==         suppressed: 0 bytes in 0 blocks
==25404== 
==25404== For counts of detected and suppressed errors, rerun with: -v
==25404== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Run Code Online (Sandbox Code Playgroud)

如果我删除了两个free()语句,这是Valgrind给我的:

$ valgrind --tool=memcheck --leak-check=full ./test
==25597== Memcheck, a memory error detector
==25597== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==25597== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==25597== Command: ./test
==25597== 
SubString is: BrownFox
==25597== 
==25597== HEAP SUMMARY:
==25597==     in use at exit: 368 bytes in 2 blocks
==25597==   total heap usage: 2 allocs, 0 frees, 368 bytes allocated
==25597== 
==25597== 72 bytes in 1 blocks are definitely lost in loss record 1 of 2
==25597==    at 0x4C2AD10: calloc (vg_replace_malloc.c:623)
==25597==    by 0x4005BF: main (test.c:8)
==25597== 
==25597== 296 bytes in 1 blocks are definitely lost in loss record 2 of 2
==25597==    at 0x4C2AD10: calloc (vg_replace_malloc.c:623)
==25597==    by 0x4005AC: main (test.c:7)
==25597== 
==25597== LEAK SUMMARY:
==25597==    definitely lost: 368 bytes in 2 blocks
==25597==    indirectly lost: 0 bytes in 0 blocks
==25597==      possibly lost: 0 bytes in 0 blocks
==25597==    still reachable: 0 bytes in 0 blocks
==25597==         suppressed: 0 bytes in 0 blocks
==25597== 
==25597== For counts of detected and suppressed errors, rerun with: -v
==25597== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Run Code Online (Sandbox Code Playgroud)

现在,如果我运行这个程序:

1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 int main(void) {
6
7    char* origstr;
8    char* newsubstr = calloc(9, sizeof(char*));
9
10   origstr = "TheQuickBrownFoxJumpedOverTheLazyDog";
11
12   strncpy(newsubstr, origstr + 8, 8);
13   printf("SubString is: %s\n", newsubstr);
14
15   free(newsubstr);
16
17   return 0;
18 }
Run Code Online (Sandbox Code Playgroud)

它显示一切都很好:

$ valgrind --tool=memcheck --leak-check=full ./test
==25862== Memcheck, a memory error detector
==25862== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==25862== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==25862== Command: ./test
==25862== 
SubString is: BrownFox
==25862== 
==25862== HEAP SUMMARY:
==25862==     in use at exit: 0 bytes in 0 blocks
==25862==   total heap usage: 1 allocs, 1 frees, 72 bytes allocated
==25862== 
==25862== All heap blocks were freed -- no leaks are possible
==25862== 
==25862== For counts of detected and suppressed errors, rerun with: -v
==25862== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Run Code Online (Sandbox Code Playgroud)

为什么我不能calloc(allocate)origstr然后给它一些东西?如果我想分配该变量并在程序过程中给它一部分另外一个字符串变量或者用它来捕获另一个返回字符串的函数的结果怎么办?那么我是否必须像处理newsubstr那样处理它?

这对我来说有点混乱,所以有人可以解释一下这是如何工作的,这样我可以更好地理解它吗?

ame*_*yCU 7

origstr = "TheQuickBrownFoxJumpedOverTheLazyDog";
Run Code Online (Sandbox Code Playgroud)

通过这样做,您可以改变指向的内容origstr.此后origstr不指向分配的内存块calloc.

并且您的free内存不是由calloc类似函数分配的,因此会导致程序出错.

使用strcpy字符串复制到origstr-

strcpy(origstr,"TheQuickBrownFoxJumpedOverTheLazyDog");
Run Code Online (Sandbox Code Playgroud)

然后你可以free指针origstr.