我正在尝试学习一些东西(只是一种爱好(,并尝试学习使用Valgrind。然而,这对我来说似乎没有意义。Valgrind似乎在说,当我在使用任何东西之前用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: %sn", newsubstr);
14
15 free(newsubstr);
16 free(origstr);
17 return 0;
18 }
以下是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)
如果我去掉两个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)
现在,如果我运行这个程序:
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: %sn", newsubstr);
14
15 free(newsubstr);
16
17 return 0;
18 }
它表明一切都很好:
$ 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)
为什么我不能调用(分配(origstr,然后给它一些东西?如果我想分配那个变量,并在程序过程中给它另一个字符串变量中的一部分,或者用它来捕获另一个返回字符串的函数的结果,该怎么办?那么我会像处理新闻订阅一样处理它吗?
这让我有点困惑,所以有人能解释一下它是如何工作的,这样我就能更好地理解它吗?
origstr = "TheQuickBrownFoxJumpedOverTheLazyDog";
通过这样做,您可以更改为origstr
所指向的内容。在此之后,CCD_ 2不指向由CCD_ 3分配的存储器块。
并且您的free
内存不是由calloc
或类似函数分配的,从而导致程序出错。
使用strcpy
将字符串复制到origstr
-
strcpy(origstr,"TheQuickBrownFoxJumpedOverTheLazyDog");
然后你可以CCD_ 8你的指针CCD_。
通过将字符串文本分配给origstr
,您不复制字符串,而只是更改origstr
的值,从而丢失指向calloc
的指针。free
和origstr
现在会导致未定义的行为。
使用strcpy
或strncpy
将字符串真正存储在堆上。但实际上,将calloc
替换为origstr
就足够了。
注:
- 正如@LeeDanielCrocker在对这个答案的评论中提到的那样,您可能打算为
char
s而不是origstr
0 s分配空间,从而大幅减少分配的内存大小。您应该将sizeof(char*)
替换为sizeof(char)
(也称为1
(
因为内存泄漏。当你重新分配指针时,它实际上不正确地分配给free()
要将内容复制到分配的指针,请使用strcpy()
strcpy(origstr, "TheQuickBrownFoxJumpedOverTheLazyDog");
让我们看看如何:
您使用
calloc()
请求内存origstring = calloc(9, sizeof(char*))
有多种原因
- 您正在为
9
指针而不是9
字符分配空间 - 您并不真正需要
calloc()
,因为您将立即覆盖内容,请使用calloc
0
- 您正在为
用字符串文字覆盖指针
origstr = "TheQuickBrownFoxJumpedOverTheLazyDog";
现在您丢失了对
calloc()
早些时候返回的指针的引用,并且无法实现free()
,您应该只返回malloc()/calloc()/realloc()
返回的free()
指针。
事实是,你不需要calloc()
oristring
指针,calloc()
/malloc()
不是用来让你分配给指针的,而是用来写指针指向的内存,或者更好的是,指向一些你可以从中读/写的内存。