使用gcc-5.2.0编译程序时,为什么valgrind无法发现泄漏?

美智

今天,我正在编写一些代码,完成后,我与进行了核对,这让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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

GCC无法编译程序

来自分类Dev

无法使用MSMPI和GCC编译程序

来自分类Dev

Eigen&GCC 5:不推荐使用std :: binder2nd类

来自分类Dev

为什么该程序使用gcc而不是g ++进行编译?

来自分类Dev

使用extern变量编译程序时出现问题

来自分类Dev

使用extern变量编译程序时出现问题

来自分类Dev

使用cuda编译程序时出现安装错误

来自分类Dev

使用SDL 2运行应用程序时Xcode 5崩溃

来自分类Dev

使用NetBeans和MinGW gcc编译C ++程序时无法运行程序makefile

来自分类Dev

为什么round(5/2)返回2?

来自分类Dev

使用GCC编译32位程序时出现奇怪的错误

来自分类Dev

使用 GCC 编译简单的 C 程序时出现 clang 错误

来自分类Dev

无法使用ES5在Angular 2中创建Pipe

来自分类Dev

如何从源代码编译gcc-5?

来自分类常见问题

使用反射覆盖2 + 2 = 5

来自分类Dev

如何使用GCC 4.4.6从RHEL6计算机编译兼容RHEL5的共享库?

来自分类Dev

如何使用gcc预处理和编译程序集文件(.s)?

来自分类Dev

无法在C ++中使用Boost和Eureqa编译程序

来自分类Dev

无法使用Geany在Ubuntu中编译程序

来自分类Dev

无法使用Geany在Ubuntu中编译程序

来自分类Dev

为什么floor(5-2 * eps)<5为假?

来自分类Dev

为什么我的gcc编译器无法识别bzip2函数,但允许我包含它们所属的库?

来自分类Dev

使用gcc与system()进行编译

来自分类Dev

为什么使用shared_ptr的atomic_load无法使用gcc 4.9编译?

来自分类Dev

如何使用tdm gcc 5.1编译wxwidget 3.1?在i5 Windows 7 64biti上使用64bit版本,并在codebloks 16上使用?

来自分类Dev

需要帮助使用gcc编译C程序

来自分类Dev

使用 gcc 编译时关闭程序

来自分类Dev

为什么使用GCC编译器的sizeof('3')== 4?

来自分类Dev

std :: find()无法使用gcc进行编译

Related 相关文章

  1. 1

    GCC无法编译程序

  2. 2

    无法使用MSMPI和GCC编译程序

  3. 3

    Eigen&GCC 5:不推荐使用std :: binder2nd类

  4. 4

    为什么该程序使用gcc而不是g ++进行编译?

  5. 5

    使用extern变量编译程序时出现问题

  6. 6

    使用extern变量编译程序时出现问题

  7. 7

    使用cuda编译程序时出现安装错误

  8. 8

    使用SDL 2运行应用程序时Xcode 5崩溃

  9. 9

    使用NetBeans和MinGW gcc编译C ++程序时无法运行程序makefile

  10. 10

    为什么round(5/2)返回2?

  11. 11

    使用GCC编译32位程序时出现奇怪的错误

  12. 12

    使用 GCC 编译简单的 C 程序时出现 clang 错误

  13. 13

    无法使用ES5在Angular 2中创建Pipe

  14. 14

    如何从源代码编译gcc-5?

  15. 15

    使用反射覆盖2 + 2 = 5

  16. 16

    如何使用GCC 4.4.6从RHEL6计算机编译兼容RHEL5的共享库?

  17. 17

    如何使用gcc预处理和编译程序集文件(.s)?

  18. 18

    无法在C ++中使用Boost和Eureqa编译程序

  19. 19

    无法使用Geany在Ubuntu中编译程序

  20. 20

    无法使用Geany在Ubuntu中编译程序

  21. 21

    为什么floor(5-2 * eps)<5为假?

  22. 22

    为什么我的gcc编译器无法识别bzip2函数,但允许我包含它们所属的库?

  23. 23

    使用gcc与system()进行编译

  24. 24

    为什么使用shared_ptr的atomic_load无法使用gcc 4.9编译?

  25. 25

    如何使用tdm gcc 5.1编译wxwidget 3.1?在i5 Windows 7 64biti上使用64bit版本,并在codebloks 16上使用?

  26. 26

    需要帮助使用gcc编译C程序

  27. 27

    使用 gcc 编译时关闭程序

  28. 28

    为什么使用GCC编译器的sizeof('3')== 4?

  29. 29

    std :: find()无法使用gcc进行编译

热门标签

归档