- 论坛徽章:
- 24
|
原帖由 incle 于 2007-9-14 16:16 发表
如果我把 mem_alloc() 放在另一个文件里面( incle.h)
#include
int mem_alloc(void)
{
char *ptr1;
char *ptr2;
printf(" Memory malloc \n");
if( (ptr1 = m ...
我知道这里的是由于没有增加 memwatch.h这个头文件.我加上后就完全可以得出内存泄露情况的日志了.
如果仔细看 memwatch.h里它有几个宏. (这是宏的巧妙之处)
- #define malloc(n) mwMalloc(n,__FILE__,__LINE__)
- #define strdup(p) mwStrdup(p,__FILE__,__LINE__)
- #define realloc(p,n) mwRealloc(p,n,__FILE__,__LINE__)
- #define calloc(n,m) mwCalloc(n,m,__FILE__,__LINE__)
- #define free(p) mwFree(p,__FILE__,__LINE__)
- #define CHECK() mwTest(__FILE__,__LINE__,MW_TEST_ALL)
- #define CHECK_THIS(n) mwTest(__FILE__,__LINE__,n)
- #define CHECK_BUFFER(b) mwTestBuffer(__FILE__,__LINE__,b)
- #define MARK(p) mwMark(p,#p,__FILE__,__LINE__)
- #define UNMARK(p) mwUnmark(p,__FILE__,__LINE__)
复制代码
当你的文件里包含了这个头文件,它就会把你代码里的 malloc等函数替换成 memwatch的函数,并且从 __FILE__ 和 __LINE__
中知道你的代码哪里分配了内存等内存操作. 从而能检查你代码里的内存泄露或都溢出等情况....
至于 __FILE__ 宏的用法,大家可以参看下面:
对于一个设计好的函数,假设它已经在一个很大的工程中到处使用,突然发现它的一个不足,想修改它的功能。也许这个新增加的功能需要一个额外的参数,但是又不想修改使用这些函数的地方。 假设有两个函数必须成对使用,一个占用资源并使用,另外一个则释放资源以供其他模块使用。典型的例子是,函数一(假设为Lock)获得一个全局的锁,这个锁用于保护在多线程情况下多个线程对一个公共资源如一个全局变量的访问。问题是,这个Lock函数获得锁以后,其他线程将不能再获得这个锁,直到当前线程释放这个锁。编制Lock函数的程序员同时提供了一个 Unlock函数用于释放锁,并要求使用Lock的人必须对应的使用Unlock。调试程序时,发现线程被死锁,怀疑有人使用完Lock后忘记调用 Unlock,但是Lock和Unlock在这个大工程中都被广泛的使用,因此设计者希望Lock和Unlock都增加两个额外的参数file和line,以说明这两个函数在哪里被调用了,哪些地方被死锁以及哪些地方调用了Lock但是没有调用Unlock。 假设这两个函数的原型为: void Lock();
void Unlock();新设计的函数的原型是: void Lock(LPCTSTR szFileName,UINT uLineNo);
void Unlock(LPCTSTR szFileName,UINT uLineNo);设计完新的函数后,项目经理希望所有模块统一使用这两个函数并提供文件名和行号信息作为参数。这样将是一个非常浩大且烦琐的工作,意味着重复性的劳动、数小时无聊的加班和工期的延误,这是谁都不愿意遇到的。 使用宏可以非常轻松的解决这一切。首先,应该把新设计的函数换个名字,不妨叫它们NewLock和NewUnlock,也就是他们的原型为: void NewLock(LPCTSTR szFileName,UINT uLineNo);
void NewUnlock(LPCTSTR szFileName,UINT uLineNo);这个函数原型应该放在一个头文件中,避免在多个地方重复的声明。需要用到这两个函数的cpp文件,只要包含他们原型所在的头文件即可。为了不改动使用Lock/Unlock函数的模块,在头文件中增加如下两行: #define Lock() NewLock(__FILE__,__LINE__)
#define Unlock() NewUnlock(__FILE,__LINE__)这样,当不同模块使用这个函数时,宏替换功能在编译时起作用,自动使用了__FILE__和__LINE__为参数,调用了新设计的函数。调试的时候就可以根据日志来判断什么地方遗漏了调用Unlock。 |
|