现在您就可以很方便的找出您的数据是何时丢失的了。至于要找出为什么delete会被调用,就要靠您自己了。
#include <MALLOC.H>
void * :perator new(size_t size) { int stackVar; unsigned long stackVarAddr = (unsigned long)&stackVar; unsigned long argAddr = (unsigned long)&size;
void ** retAddrAddr = (void **)(stackVarAddr/2 + argAddr/2 + 2);
void * retAddr = * retAddrAddr;
unsigned char *retBuffer = (unsigned char*)malloc(size + 16);
memset(retBuffer, 0, 16);
memcpy(retBuffer, &retAddr, sizeof(retAddr));
memcpy(retBuffer + 4, &size, sizeof(size));
return retBuffer + 16; }
void :perator delete(void *buf) { int stackVar; if(!buf) return;
unsigned long stackVarAddr = (unsigned long)&stackVar; unsigned long argAddr = (unsigned long)&buf;
void ** retAddrAddr = (void **)(stackVarAddr/2 + argAddr/2 + 2);
void * retAddr = * retAddrAddr;
unsigned char* buf2 = (unsigned char*)buf;
buf2 -= 8;
memcpy(buf2, &retAddr, sizeof(retAddr));
size_t size;
buf2 -= 4;
memcpy(&size, buf2, sizeof(buf2));
buf2 += 8;
buf2[0] = 0xde; buf2[1] = 0xad; buf2[2] = 0xbe; buf2[3] = 0xef;
buf2 += 4;
memset(buf2, 0x7777, size);
// deallocating destroys saved addresses, so dont // buf -= 16; // free(buf); }
其它值得关注的地方:
这段代码同样可以用于内存泄露的检测。只需修改delete运算符使它真正的去释放内存,并且在程序退出前,用__heapwalk遍历所有已分配的内存块并把调用new的地址提取出来,这就将得到一份没有被delete匹配的new调用列表。 还要注意的是:这里列出的代码只能在调试的时候去使用,如果你把它段代码放到最终的产品中,会导致程序运行时内存被大量的消耗。
|