今天,我正在编写一些代码,完成后,我与进行了核对,这让valgrind
我感到惊讶。
如果我使用gcc-4.9.2在Ubuntu(15.04 64BIT)上使用以下命令编译程序:
gcc -Wextra -Werror -Wstrict-prototypes -Wconversion --std=c11 -O2 -g program.c -o program
然后运行valgrind:
valgrind --leak-check=full --track-origins=yes ./program
我得到以下输出:
==5325== Memcheck, a memory error detector ==5325== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==5325== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==5325== Command: ./program ==5325== Bye ==5325== ==5325== HEAP SUMMARY: ==5325== in use at exit: 33 bytes in 1 blocks ==5325== total heap usage: 1 allocs, 0 frees, 33 bytes allocated ==5325== ==5325== 33 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==5325== at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5325== by 0x4004BD: main (program.c:11) ==5325== ==5325== LEAK SUMMARY: ==5325== definitely lost: 33 bytes in 1 blocks ==5325== indirectly lost: 0 bytes in 0 blocks ==5325== possibly lost: 0 bytes in 0 blocks ==5325== still reachable: 0 bytes in 0 blocks ==5325== suppressed: 0 bytes in 0 blocks ==5325== ==5325== For counts of detected and suppressed errors, rerun with: -v ==5325== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
如您所见,发现了泄漏,但是请看一下使用gcc-5.2.0进行以下编译时会发生什么:
./install/gcc-5.2.0/bin/gcc5.2 -Wextra -Werror -Wstrict-prototypes -Wconversion --std=c11 -O2 -g program.c -o program
现在,valgrind说:
==5344== Memcheck, a memory error detector ==5344== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==5344== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==5344== Command: ./program ==5344== Bye ==5344== ==5344== HEAP SUMMARY: ==5344== in use at exit: 0 bytes in 0 blocks ==5344== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==5344== ==5344== All heap blocks were freed -- no leaks are possible ==5344== ==5344== For counts of detected and suppressed errors, rerun with: -v ==5344== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
如您所见,总的堆使用情况:0分配,0释放,0字节分配
我尝试的代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void){
int a = 0;
size_t len1 = 0, len2 = 0;
char *string1 = "Hello";
char *string2;
string2 = malloc(33);
strcpy(string2, "Hello");
len1 = strlen(string1);
len2 = strlen(string2);
if(len1 != len2){
a = 5;
}else{
a=4;
}
while (a != -1){
if(a == 2){
break;
}
a--;
}
printf("Bye\n");
/*free(string2);*/
return 0;
}
使用此方法安装了GCC-5.2.0 。
现在我的问题是:是GCC还是valgrind有故障?为什么会发生这种情况,我该如何避免呢?
最后一件事,如果我更改:
printf("Bye\n");
对此:
printf("String2 = %s\n",string2);
发现泄漏:
==5443== Memcheck, a memory error detector ==5443== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==5443== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==5443== Command: ./program ==5443== String2 = Hello ==5443== ==5443== HEAP SUMMARY: ==5443== in use at exit: 33 bytes in 1 blocks ==5443== total heap usage: 1 allocs, 0 frees, 33 bytes allocated ==5443== ==5443== 33 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==5443== at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5443== by 0x40044D: main (program.c:11) ==5443== ==5443== LEAK SUMMARY: ==5443== definitely lost: 33 bytes in 1 blocks ==5443== indirectly lost: 0 bytes in 0 blocks ==5443== possibly lost: 0 bytes in 0 blocks ==5443== still reachable: 0 bytes in 0 blocks ==5443== suppressed: 0 bytes in 0 blocks ==5443== ==5443== For counts of detected and suppressed errors, rerun with: -v ==5443== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
这让我问自己为什么?在某种程度上,printf()有助于解决这个问题。
看来,GCC 5.2.0能够检测出string2
是恒定的"Hello"
通过strcpy
。因此,它只是优化而string2
无需在HEAP中分配新的内存块。我的猜测是,string.h
有实施strcpy
,并strlen
在头本身。
检测内存泄漏的最佳方法是无需优化即可进行编译。尝试使用-O0
而不是进行重新编译-O2
。在这种情况下,编译器将创建尽可能接近您的源代码的二进制文件。
有了这个:
printf(“ String2 =%s \ n”,string2);
发现泄漏:
在这里,似乎编译器检测到string2
对它的依赖,因此它不会对其进行优化。可能是因为在printf
您的源代码编译时无法实现的实现,或者可能是因为printf
使用了可变参数。但这只是我的猜测...
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句