linux 内存泄露检测 mtrace

    xiaoxiao2024-04-23  103

    参考

    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.log export MALLOC_TRACE

    3,编译和运行程序

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

    4,查看内存报告

    mtrace mt.o mt.log

    可以看到:

    Memory not freed: ----------------- Address Size Caller 0x0000000000d65460 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 Caller 0x000000000125d460 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 0x1eb9468 new 0x1eb9469 new 0x1eb946a new 0x1eb946b new 0x1eb946c new 0x1eb946d new 0x1eb946e new 0x1eb946f new 0x1eb9470 new 0x1eb9471 addr of pc: 0x1eb9468 size of pc: 8 size of class C: 1, 1

    内存泄露检测

    Memory not freed: ----------------- Address Size Caller 0x0000000001eb9460 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 0x13d3468 new 0x13d3469 new 0x13d346a new 0x13d346b new 0x13d346c new 0x13d346d new 0x13d346e new 0x13d346f new 0x13d3470 new 0x13d3471 addr of pc: 0x13d3468 size of pc: 8 size of class C: 1, 1 delete 0x13d3468 *** Error in `./new': munmap_chunk(): invalid pointer: 0x00000000013d3468 *** Aborted

    查看内存泄露文件mt.log

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

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

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

    对应的输出是

    new 0x1f7a468 new 0x1f7a469 new 0x1f7a46a new 0x1f7a46b addr of pc: 0x1f7a468 size of pc: 8 size of class C: 1, 1 delete 0x1f7a468 Segmentation 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 0x108c468 new 0x108c469 new 0x108c46a new 0x108c46b new 0x108c46c new 0x108c46d new 0x108c46e new 0x108c46f new 0x108c470 new 0x108c471 delete 0x108c471 delete 0x108c470 delete 0x108c46f delete 0x108c46e delete 0x108c46d delete 0x108c46c delete 0x108c46b delete 0x108c46a delete 0x108c469 delete 0x108c468

    内存泄露查看:No memory leaks.

    转载请注明原文地址: https://ju.6miu.com/read-1288272.html
    最新回复(0)