linux 内存泄露检测 mtrace

来源:互联网 发布:controlnet软件下载 编辑:程序博客网 时间:2024/04/23 16:15

参考

mtrace

实验

1,写一个内存泄露的程序mt.c

#include <stdlib.h>#include <mcheck.h>int main(){        mtrace();        int *a;        a = malloc(sizeof(int));        muntrace();        return 0;}

加上头文件
#include <mcheck.h>

然后在main()函数的开头加上
mtrace();

在main函数返回前加上
muntrace();

2,设置环境变量

MALLOC_TRACE=/home/stevewong/mtrace/mt.logexport MALLOC_TRACE

3,编译和运行程序

gcc mt.c -g mt.o./mt.o

4,查看内存报告

mtrace mt.o mt.log

可以看到:

Memory not freed:-----------------           Address     Size     Caller0x0000000000d65460      0x4  at /home/stevewong/mtrace/mt.c:7

5,正确的程序mtfree.c

#include <stdlib.h>#include <mcheck.h>int main(){        mtrace();        int *a;        a = malloc(sizeof(int));        if (a == NULL)                return 1;        free(a);        muntrace();        return 0;}

6,编译,运行,查看内存泄露的情况

No memory leaks.

7,测试一下new的泄露是否能检测出来

#include <stdlib.h>#include <new>#include <mcheck.h>using namespace std;int main(){        mtrace();        int *a;        a = new int[10];        muntrace();        return 0;}
Memory not freed:-----------------           Address     Size     Caller0x000000000125d460     0x28  at 0x7fb584cc82e8

0x28就是40个字节,正好对应10个int。

再来看一个类的例子

include <stdlib.h>#include <new>#include <mcheck.h>#include <iostream>using namespace std;class C{public:        C()        {                cout << "new " << this << endl;        }        ~C()        {                cout << "delete " << this << endl;        }};int main(){        mtrace();        C *pc;        pc = new C[10];        cout << "addr of pc: " << pc << endl;        cout << "size of pc: " << sizeof(pc) << endl;        cout << "size of class C: "<< sizeof(C) << ", " << sizeof(pc[0]) << endl;        //delete []pc;        muntrace();        return 0;}

输出:

new 0x1eb9468new 0x1eb9469new 0x1eb946anew 0x1eb946bnew 0x1eb946cnew 0x1eb946dnew 0x1eb946enew 0x1eb946fnew 0x1eb9470new 0x1eb9471addr of pc: 0x1eb9468size of pc: 8size of class C: 1, 1

内存泄露检测

Memory not freed:-----------------           Address     Size     Caller0x0000000001eb9460     0x12  at 0x7fefd2c802e8

一个只有构造函数和析构函数的类占1个字节(构造函数和析构函数不占空间),10个空类10个字节,但是内存泄露检测显示size是0x12也就是18个字节,多出来的8个字节是?

使用gdb查看内存可以发现
display *((int*)0x1eb9460)

结果是10。说明这8个字节是存了数组的长度。

可以参考以下文章:
C++对象模型之简述C++对象的内存布局

如果只是delete了pc,没有delete整个对象数组呢?

#include <stdlib.h>#include <new>#include <mcheck.h>#include <iostream>using namespace std;class C{public:        C()        {                cout << "new " << this << endl;        }        ~C()        {                cout << "delete " << this << endl;        }};int main(){        mtrace();        C *pc;        pc = new C[4];        cout << "addr of pc: " << pc << endl;        cout << "size of pc: " << sizeof(pc) << endl;        cout << "size of class C: "<< sizeof(C) << ", " << sizeof(pc[0]) << endl;        delete pc;        muntrace();        return 0;}

只调用了一个析构函数,然后就出错了。

new 0x13d3468new 0x13d3469new 0x13d346anew 0x13d346bnew 0x13d346cnew 0x13d346dnew 0x13d346enew 0x13d346fnew 0x13d3470new 0x13d3471addr of pc: 0x13d3468size of pc: 8size of class C: 1, 1delete 0x13d3468*** Error in `./new': munmap_chunk(): invalid pointer: 0x00000000013d3468 ***Aborted

查看内存泄露文件mt.log

- 0x00000000013d3468 Free 3 was never alloc'd /home/stevewong/mtrace/new.c:29Memory not freed:-----------------           Address     Size     Caller0x00000000013d3460     0x12  at 0x7f0ab50e52e8

泄露的长度是0x12=18,也就说所有的内存都没被释放。

这里有个有趣的问题,如果把数组长度设置为4的话,并没有内存泄露,而是出现了segmentation fault。求高手指教一下这是为什么。

对应的输出是

new 0x1f7a468new 0x1f7a469new 0x1f7a46anew 0x1f7a46baddr of pc: 0x1f7a468size of pc: 8size of class C: 1, 1delete 0x1f7a468Segmentation fault

对应的内存泄露文件是
No memory leaks.

8,还是把new的例子写好看看情况

#include <stdlib.h>#include <new>#include <mcheck.h>#include <iostream>using namespace std;class C{public:        C()        {                cout << "new " << this << endl;        }        ~C()        {                cout << "delete " << this << endl;        }};int main(){        mtrace();        C *pc;        pc = new C[10];        delete []pc;        muntrace();        return 0;}

输出:

new 0x108c468new 0x108c469new 0x108c46anew 0x108c46bnew 0x108c46cnew 0x108c46dnew 0x108c46enew 0x108c46fnew 0x108c470new 0x108c471delete 0x108c471delete 0x108c470delete 0x108c46fdelete 0x108c46edelete 0x108c46ddelete 0x108c46cdelete 0x108c46bdelete 0x108c46adelete 0x108c469delete 0x108c468

内存泄露查看:No memory leaks.

0 0
原创粉丝点击