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\r\n", pszFunc, uLine);
return malloc(uSize);   //调用标准C库的malloc.
}

void my_free(void *pPtr, const char *pszFunc, unsigned int uLine)
{
printf("FREE: func:%s; line:%d\r\n", 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

重新定义malloc和free 防止内存泄漏的更多相关文章

  1. Dynamically allocated memory 动态分配内存【malloc】Memory leaks 内存泄漏

    内存泄露Memory leaks :没有指针指向原来a分配出来的那段空间了

  2. 一个跨平台的 C++ 内存泄漏检测器

    2004 年 3 月 01 日 内存泄漏对于C/C++程序员来说也可以算作是个永恒的话题了吧.在Windows下,MFC的一个很有用的功能就是能在程序运行结束时报告是否发生了内存泄漏.在Linux下, ...

  3. 关于new/delete、malloc/free的内存泄漏检测

    情况一 new/delete 内存泄漏 1.在MFC中可以每一个cpp文件的头部添加以下一段宏来检测new申请而没用free释放的内存泄漏 #ifdef _DEBUG #define new DEBU ...

  4. malloc钩子和内存泄漏工具mtrace、Valgrind

    一:malloc钩子函数 static void* (* old_malloc_hook) (size_t,const void *);static void (* old_free_hook)(vo ...

  5. 内存泄漏之malloc替换方法

    //内存泄漏之malloc替换方法 //内存泄漏之malloc替换方法#include "stdio.h"#include "stdlib.h" /*文件路径名 ...

  6. 技术干货丨通过wrap malloc定位C/C++的内存泄漏问题

    摘要:用C/C++开发的程序执行效率很高,但却经常受到内存泄漏的困扰.本文提供一种通过wrap malloc查找memory leak的思路. 用C/C++开发的程序执行效率很高,但却经常受到内存泄漏 ...

  7. C++内存泄漏检测

    CRT检测 定位内存泄漏位置 #include "stdafx.h" #ifdef _DEBUG #define DEBUG_NEW new( _NORMAL_BLOCK, __F ...

  8. Js中常见的内存泄漏场景

    常见的内存泄漏场景 内存泄漏Memory Leak是指程序中已动态分配的堆内存由于疏忽或错误等原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果.内存泄漏并非指内 ...

  9. iOS中滤镜处理及相关内存泄漏问题的解决

    最近工作之余在做一个美图秀秀的仿品 做到滤镜这块的时候  自己就参考了网上几位博主(名字忘了记,非常抱歉)的博客,但是发现跟着他们的demo做的滤镜处理,都会有很严重的内存泄漏,于是就自己按照大体的思 ...

随机推荐

  1. Codeforces 437B The Child and Set

    题目链接:Codeforces 437B The Child and Set 開始是想到了这样的情况,比方lowbit之后从大到小排序后有这么几个数,200.100,60.50.S = 210.那先选 ...

  2. JQuery的Ajax跨域请求的

    JQuery的Ajax跨域请求的(Ajax) 什么是jsonp格式呢?API原文:假设获取的数据文件存放在远程server上(域名不同.也就是跨域获取数据),则须要使用jsonp类型.使用这样的类型的 ...

  3. Android 解屏幕锁与点亮屏幕(来电时效果)

    PowerManager pm=(PowerManager) getSystemService(Context.POWER_SERVICE); //获取电源管理器对象 PowerManager.Wak ...

  4. [PWA] 8.Unobtrusive update: Delete old cache and only keep one, hard refresh to let new SW to take control

    So once you modify the code, service worker will auto create a new one and it won't take control ove ...

  5. JAVA复习2 JAVA开发环境配置

    我想写的东西主要是JAVA编程里的难点和易混淆点,所以在这里给大家提供一些经典的博客地址或网址.. W3C JAVA教程  JAVA开发环境配置篇: http://www.w3cschool.cc/j ...

  6. [转] FDA批准首个莫米松植入式给药系统用于治疗慢性鼻窦炎

    from: http://www.qqyy.com/jibing/erbihouke/111020/3fd2f.html http://www.chemdrug.com/news/231/5/2494 ...

  7. 从实践谈iOS生命周期

    从实践谈iOS生命周期 个人感觉生命周期无论在Android,还是iOS都是很重要的概念,因为在每个声明周期的状态下我们可以做很多预加载或者处理的操作.因此在这里主要总结下ViewController ...

  8. UITextField控件处理键盘弹出时遮住输入框的问题

    原文连接: http://www.devdiv.com/thread-70159-1-1.html 实现以下三个方法,如果弹出的键盘会遮住输入框 ,整体的界面会向上移动,这样就不会遮住输入框了.自己增 ...

  9. php laravel mysql无法连接处理方案(linux服务器配置)

    阿里云 Ubuntu 14.*上搭建laravel环境 之前做项目时都是搭建在自己的服务器上,可是自己的那个服务器是很久以前一点点配置好的,也是各种百度,该忘记的都忘了, 所以前一段在客户的阿里云Ub ...

  10. 5事件DOM零级事件跟DOM二级事件

    事件的行为传播,行为本身跟事件绑定没有关系:1.全新认识事件(某一个具体的行为)->行为本身:浏览器天生自带的一些行为操作->click,mouseover(mouseenter),mou ...