zoukankan      html  css  js  c++  java
  • 重新定义malloc和free 防止内存泄漏

    1, 定义供应用程序使用的头文件
    //libmem.h
    #ifndef _LIBMEM_H_
    #define _LIBMEM_H_

    //声明自定义malloc及free函数
    extern void *my_malloc(unsigned int uSize, const char *pszFunc, unsigned int uLine);
    extern void my_free(void *pPtr, const char *pszFunc, unsigned int uLine);

    //重定义malloc及free
    #define malloc(size) my_malloc(size, __FUNCTION__, __LINE__)
    #define free(ptr) my_free(ptr, __FUNCTION__, __LINE__);

    #endif


    2, 定义my_malloc及my_free.
    //libmem.c
    //注意: 这里千万不要包含mymem.h, 否则程序陷入死循环, 原因你是知道的.
    #include <stdlib.h>   //标准c库的头文件, malloc及free需要试用.
    #include <stdio.h>
    void *my_malloc(unsigned int uSize, const char *pszFunc, unsigned int uLine)
    {
    printf("MALLOC: func:%s; line:%d ", pszFunc, uLine);
    return malloc(uSize);   //调用标准C库的malloc.
    }

    void my_free(void *pPtr, const char *pszFunc, unsigned int uLine)
    {
    printf("FREE: func:%s; line:%d ", pszFunc, uLine);
    return free(pPtr);   //调用标准C库的free.
    }


    3, 编译库
           gcc -o libmem.o -c libmem.c
           ar rc libmem.a libmem.o

    4, 使用自定义的malloc及free.
    //test.c
    #include <stdlib.h>
    int main(int argc, char **argv)
    {
    int *p = malloc(100);
    free(p);
    return 0;
    }


    编译连接:  
       gcc -o test.o -c test.c
       gcc -L./ -o test test.o -lmem

    怎么我们自定义函数中的printf没有起作用? 别急, 因为我们在test.c中没有包含自己的头文件, 系统使用了默认的库.将#include <stdlib.h> 换成 #include "libmem.h", 大功告成!

    什么? 在很多文件中都调用了malloc和free函数,你不想到每个文件中去添加头文件? 没关系, 稍多做一点工作就可以完成。
    第一, 修改宏定义及自定义my_malloc和my_free的参数列表, 使宏malloc/free, 自定义my_malloc/my_free的参数与libc中的malloc/free完全一致, 比如malloc的参数必须是unsigned int, 而不是int。
    //声明自定义malloc及free函数,
    extern void *my_malloc(unsigned int uSize);
    extern void my_free(void *pPtr);
    //重定义malloc及free
    #define malloc(size) my_malloc(size)
    #define free(ptr) my_free(ptr);

    否则, 若包含stdlib.h, 在预编译阶段将stdlib.h中malloc申明展开。
    extern void *malloc(size_t __size) __THROW __attribute_malloc__ __wur;
    被展开为:
    extern void *my_malloc(size_t __size, __FUNCTION__, __LINE__) __THROW __attribute_malloc__ __wur;
    这是错误的申明方式
    第二:编译
       gcc -o test.o -include mymem.h -c test.c
       gcc -L./ -o test test.o -lmem
    注: 有些函数不能用上面的方法, 比如_exit, 必须去掉文件中包含的unistd.h, 再包含自定义的头文件.否则, 运行的时候会出现意想不到的结果.

    5, 意义.
       可以自己跟踪动态内存使用情况, 当实现内存泄漏监测时就可用到.在写内存泄漏程序时要注意的:
    5.1 使用上面第一种方式,
           #define malloc(size) my_malloc(size, __FUNCTION__, __LINE__)
           #define free(ptr) my_free(ptr, __FUNCTION__, __LINE__);
       因为这样可以跟踪分配及释放内存的具体位置。
    5.2 每次调用malloc时, 将调用的具体位置(file, function, line), 内存的起始地址, 内存长度等记录下来, 放在链表中。每次调用free时, 删除链表中相应的记录。
    5.3 分配时, 多分配一定数目的内存, 返回所分配内存的起始地址, 并将多分配的那一段的内存初始化为预定义的值。 以便在后续调用free时检查多分配的那一段内存的值, 看其值是否为预定义的值, 否则有非法内存访问。
    5.4 malloc时, 检查所分配的内存是否在链表中, 若是, 则内存分配有误。free时, 检查所释放的内存起始地址是否在链表中, 若是, 则释放该段内存,并删除链表中的记录; 否则, 为释放时非法内存。
    5.5 strdup 也分配了内存, 用上面的方法无法跟踪, 可用跟malloc/free相同的方法自定义strdup.
    5.6 new/delete, 可以用同样的方法做内存检测。

    http://blog.csdn.net/jiangxinyu/article/details/7780211

  • 相关阅读:
    SQLite的SQL语法
    C/C++中各种类型int、long、double、char表示范围(最大最小值)
    君子性非异也,善假于物也
    简单工厂模式
    Linux下通配符总结
    Readprocessmemory使用方法
    C++ 清空消息队列
    一周自学动态站点设计
    iOS 8.0正式公布啦
    What is the difference between JRE,JVM and JDK?
  • 原文地址:https://www.cnblogs.com/findumars/p/5811486.html
Copyright © 2011-2022 走看看