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