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. getconf 取系统配制 --CPU

    cpu 缓存:getconf -a LEVEL1_ICACHE_SIZE LEVEL1_ICACHE_ASSOC LEVEL1_ICACHE_LINESIZE LEVEL1_DCACHE_SIZE L ...

  2. 安全框架Shiro和Spring Security比较

    Shiro 首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势. Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证. ...

  3. POJ 2049 Finding Nemo

    Finding Nemo Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 8631   Accepted: 2019 Desc ...

  4. 【开源java游戏框架libgdx专题】-13-开发工具-地图的使用

    支持libGDX的地图编辑器有很多种,其中比较常用的工具为Tiled地图工具.Tiled是一款非常好用的地图编辑器.下载地址:http://www.mapeditor.org TiledMap类: 又 ...

  5. Log4net 配置注意事项

    1. 首先引入Log4net程序集 2.修改webconfig配置文件 在 configuration 节点下面添加如下节点 <configSections> <section na ...

  6. UniqueID和ClientID的来源

    在<漫话ID>一文中,作者提出了一个问题:为什么在ItemCreated事件中访问ClientID会导致MyButton无法响应事件,事实上 MyButton无法响应事件是因为他在客户端的 ...

  7. OpenXmlSdk导出Excel

    感觉OpenXmlSdk的语法真的不是很友好.研究了半天,只实现了简单的导出功能.对于单元格样式的设置暂时还是搞明白,网上的资料真的很少,官方文档是英文的.中文的文章大都是用工具(Open XML S ...

  8. CRT detected that the application wrote to memory after end of heap buffer.

    很多人的解释都不一样,  我碰到的问题是,开辟的内存空间小于操作的内存空间.也就是说,我free的内存越界了. 这是我开辟链表结构体内存的代码: PNODE Create() { int len; / ...

  9. archlinux的安装与简单配置(长期更新)

    安装部分较为较为简略,详细内容请查看arch的wiki 分区 cfdisk 格式化 mkfs.ext4 /dev/sdaX ... 挂载分区 mount /dev/sdaX /mnt ... 修改软件 ...

  10. 富文本web编辑器(UEditor)

    展示效果: