在Linux下些C语言程序,最大的问题就是没有一个好的编程IDE,当然想kdevelop等工具都相当的强大,但我还是习惯使用kdevelop工具,由于没有一个习惯的编程IDE,内存检测也就成了在Linux下编写程序的一个大问题。

 
 是不是说没有一种内存检查工具能够在Linux使用呢,也不是,像valgrind工具还是相当不错的。他的下载地址是
http://valgrind.org/downloads /current.html#current 下载一个valgrind 3.2.3
(tar.bz2)
工具,按照里面的README提示,安装后就可以使用这个工具来检测内存泄露和内存越界等。这是一个没有界面的内存检测工具,安装后,输入
valgrind ls -l 验证一下该工具是否工作正常(这是README里面的方法,实际上是验证一下对ls
-l命令的内存检测),如果你看到一堆的信息说明你的工具可以使用了。

  在编译你的程序时,请设置-g参数,编译出后使用如下的命令来判断你的程序存在内存泄露:

  valgrind --tools=memcheck --leak-check=full yourProg在输出信息中就会看到你的内存问题了。关于这些参数是什么意思可以参考valgrind --help 的输出信息。

Linux C 编程内存泄露检测工具(一):mtrace
前言

所有使用动态内存分配(dynamic memory allocation)的程序都有机会遇上内存泄露(memory leakage)问题,在Linux里有三种常用工具来检测内存泄露的情況,包括:

1. mtrace
   2. dmalloc
   3. memwatch

1. mtrace

mtrace是三款工具之中是最简单易用的,mtrace是一个C函數,在<mcheck.h>里声明及定义,函数原型为:
    void mtrace(void);


实mtrace是类似malloc_hook的 malloc handler,只不过mtrace的handler
function已由系统为你写好,但既然如此,系统又怎么知道你想将malloc/free的记录写在哪里呢?为此,调用mtrace()前要先设置
MALLOC_TRACE环境变量:
    #include <stdlib.h>
    ....
    setenv("MALLOC_TRACE", "output_file_name", 1);
    ...

「output_file_name」就是储存检测结果的文件的名称。

但是检测结果的格式是一般人无法理解的,而只要有安装mtrace的话,就会有一名为mtrace的Perl script,在shell输入以下指令:
    mtrace [binary] output_file_name

就会将output_file_name的內容转化成能被理解的语句,例如「No memory leaks」,「0x12345678 Free 10 was never alloc」诸如此类。

例如以下有一函数:(暂且放下single entry single exit的原则)
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <mcheck.h>
    int main() {
        char *hello;
   
        setenv("MALLOC_TRACE", "output", 1);
        mtrace();
        if ((hello = (char *) malloc(sizeof(char))) == NULL) {
            perror("Cannot allocate memory.");
            return -1;
        }

return 0;
    }

执行后,再用mtrace 将结果输出:
    - 0x08049670 Free 3 was never alloc'd 0x42029acc
    - 0x080496f0 Free 4 was never alloc'd 0x420dc9e9
    - 0x08049708 Free 5 was never alloc'd 0x420dc9f1
    - 0x08049628 Free 6 was never alloc'd 0x42113a22
    - 0x08049640 Free 7 was never alloc'd 0x42113a52
    - 0x08049658 Free 8 was never alloc'd 0x42113a96

Memory not freed:
    -----------------
       Address     Size     Caller
    0x08049a90      0x1  at 0x80483fe

最后一行标明有一个大小为1 byte的内存尚未释放,大概是指「hello」吧。
    若我们把该段内存释放:
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <mcheck.h>
    int main() {
        char *hello;
  
        setenv("MALLOC_TRACE", "output", 1);
        mtrace();
        if ((hello = (char *) malloc(sizeof(char))) == NULL) {
            perror("Cannot allocate memory.");
            return -1;
        }

free(hello);
        return 0;
    }

结果如下:
    - 0x080496b0 Free 4 was never alloc'd 0x42029acc
    - 0x08049730 Free 5 was never alloc'd 0x420dc9e9
    - 0x08049748 Free 6 was never alloc'd 0x420dc9f1
    - 0x08049668 Free 7 was never alloc'd 0x42113a22
    - 0x08049680 Free 8 was never alloc'd 0x42113a52
    - 0x08049698 Free 9 was never alloc'd 0x42113a96
    No memory leaks.

mtrace的原理是记录每一对malloc-free的执行,若每一个malloc都有相应的free,则代表没有内存泄露,对于任何非malloc/free情況下所发生的内存泄露问题,mtrace并不能找出来。

Memwatch简介


三种检测工具当中,设置最简单的算是memwatch,和dmalloc一样,它能检测未释放的内存、同一段内存被释放多次、位址存取错误及不当使用未分
配之内存区域。请往http://www.linkdata.se/sourcecode.html下载最新版本的Memwatch。
安装及使用memwatch

很幸运地,memwatch根本是不需要安装的,因为它只是一组C程序代码,只要在你程序中加入memwatch.h,编译时加上-DMEMWATCH -DMW_STDIO及memwatch.c就能使用memwatch,例如:
gcc -DMEMWATCH -DMW_STDIO test.c memwatch.c -o test

memwatch输出結果

memwatch

的输出文件名称为memwatch.log,而且在程序执行期间,所有错误提示都会显示在stdout上,如果memwatch未能写入以上文件,它会尝
试写入memwatchNN.log,而NN介于01至99之间,若它仍未能写入memwatchNN.log,则会放弃写入文件。

我们引用第一篇(mtrace)中所使用过的有问题的代码:
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <memwatch.h>
    int main() {
        char *hello;

setenv("MALLOC_TRACE", "output", 1);
        mtrace();
        if ((hello = (char *) malloc(sizeof(char))) == NULL) {
            perror("Cannot allocate memory.");
            return -1;
        }

return 0;
    }

然后在shell中输入以下编译指令:
    gcc -DMEMWATCH -DMW_STDIO test.c memwatch.c -o test

memwatch.log的內容如下:
    ============= MEMWATCH 2.71 Copyright (C) 1992-1999 Johan Lindh =============

Started at Sat Jun 26 22:48:47 2004

Modes: __STDC__ 32-bit mwDWORD==(unsigned long)
    mwROUNDALLOC==4 sizeof(mwData)==32 mwDataSize==32

Stopped at Sat Jun 26 22:48:47 2004

unfreed: <1> test.c(9), 1 bytes at 0x805108c    {FE .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .}

Memory usage statistics (global):
     N)umber of allocations made: 1
     L)argest memory usage      : 1
     T)otal of all alloc() calls: 1
     U)nfreed bytes totals      : 1

文件指出,在test.c被执行到第9行时所分配的内存仍未被释放,该段内存的大小为1 byte。
Memwatch使用注意

Memwatch

的优点是无需特別配置,不需安装便能使用,但缺点是它会拖慢程序的运行速度,尤其是释放内存时它会作大量检查。但它比mtrace和dmalloc多了一
项功能,就是能模拟系统内存不足的情況,使用者只需用mwLimit(long num_of_byte)函数来限制程式的heap
memory大小(以byte单位)。

最详细的使用说明(包括优点缺点,运行原理等)已在README中列出,本人强烈建议各位读者参考该文件

Linux c内存泄漏检测的更多相关文章

  1. linux c++ 内存泄漏检测工具:AddressSanitizer(ASan)

    1.介绍 AddressSanitizer(ASan),该工具为gcc自带,4.8以上版本均可以使用. 2.使用 编译的方式很简单,只需要添加 -fsanitize=address -g 即可,如 g ...

  2. C++内存泄漏检测工具

    C++内存泄漏检测工具 1.VC自带的CRT:_CrtCheckMemory   调试器和 CRT 调试堆函数 1.1用法: /************************************ ...

  3. C++程序内存泄漏检测方法

    一.前言 在Linux平台上有valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是跑服务器,再加上它的开源属性,相对而言,处理问题容易形成“统一”的标准.而在W ...

  4. Android内存泄漏检测利器:LeakCanary

    Android内存泄漏检测利器:LeakCanary MAR 28TH, 2016 是什么? 一言以蔽之:LeakCanary是一个傻瓜化并且可视化的内存泄露分析工具 为什么需要LeakCanary? ...

  5. C/C++的内存泄漏检测工具Valgrind memcheck的使用经历

    Linux下的Valgrind真是利器啊(不知道Valgrind的请自觉查看参考文献(1)(2)),帮我找出了不少C++中的内存管理错误,前一阵子还在纠结为什么VS 2013下运行良好的程序到了Lin ...

  6. C的内存泄漏检测

    一,Windows平台下的内存泄漏检测 检测是否存在内存泄漏问题 Windows平台下面Visual Studio 调试器和 C 运行时 (CRT) 库为我们提供了检测和识别内存泄漏的有效方法,原理大 ...

  7. Linux下内存泄漏工具【转】

    转自:http://www.cnblogs.com/guochaoxxl/p/6970090.html 概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况 ...

  8. Linux下内存泄漏工具

    概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的.复杂的应用程序中,内存泄漏是常见的问题.当以前分配的一片内存不再需要使用或无法访问时,但是却 ...

  9. 利用Android Studio、MAT对Android进行内存泄漏检测

    利用Android Studio.MAT对Android进行内存泄漏检测 Android开发中难免会遇到各种内存泄漏,如果不及时发现处理,会导致出现内存越用越大,可能会因为内存泄漏导致出现各种奇怪的c ...

随机推荐

  1. iOS,APP退到后台,获取推送成功的内容并且语音播报内容。

    老铁,我今天忙了一下午就为解决这个问题,网上有一些方法,说了一堆关于这个挂到后台收到推送并且获得推送内容的问题,有很多人都说APP挂到后台一会就被杀死.但实际上可以有办法解决的. WechatIMG3 ...

  2. initWithNibName/awakeFromNib/initWithCoder

    转自: http://leeyin.iteye.com/blog/1040362 每个ios开发者对loadView和viewDidLoad肯定都很熟悉,虽然这两个函数使用上真的是非常简单,但是和类似 ...

  3. Active Directory网域

    Active Directory网域 3.1Windows网络的管理方式 3.1.1工作组模式 工作组由一组用网络连接在一起的计算机组成,他们将计算机内的资源共享给用户访问.工作组网络也被称为“对等式 ...

  4. JDBC连接数据库详解

    JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通过java.la ...

  5. baidumap demo(一)

    覆盖物概述 地图上自定义的标注点和覆盖物我们统称为地图覆盖物.您可以通过定制BMKAnnotation和BMKOverlay来添加对应的标注点和覆盖物.地图覆盖物的设计遵循数据与View分离的原则,B ...

  6. ios之UITextfield

    //初始化textfield并设置位置及大小   UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 13 ...

  7. python--网络编程之socket

    一 . 网络编程 CS架构 客户端服务端架构 服务端:提供服务的 客户端:享受服务的 BS架构:浏览器和服务端 网络通信流程: 集线器:将所有连接上它的电脑全部联通起来 交换机:升级版的集线器 网卡: ...

  8. 【LeetCode】Spiral Matrix(螺旋矩阵)

    这是LeetCode里的第54道题. 题目要求: 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素. 示例 1: 输入: [ [ 1, 2, 3 ...

  9. Bin Paking Problem:简单的构造性算法

    *本文主要记录和分享学习到的知识,算不上原创 *参考文献见链接 目录 BL和BLF算法 BF算法 HR算法 PH算法

  10. 【软考5】解释型 or 编译型

    导读:在上篇博客中,我们了解到,目前的编码语言经过不断的发展,已经经历了机器语言--汇编语言--高级语言的过程.虽然我们的编码语言在不停的升级,但作为计算机来说,它始终是一个只能理解0和1构成的机器语 ...