C++内存泄露

C++内存泄露一直是个头痛的问题,但是总要解决吧,在网上搜了很久以后,终于找到了一个不是办法的办法,这个办法有缺陷,但是有总比没有强吧!
使用的编译器:VS2010。
这里需要说点汇编的知识:
void fun(int nVal)
{
}
当调用函数fun(a)时,首先a会入栈,其次是返回地址会入栈,我们可以重载operator new和operator delete来记录每个调用的地址,然后用链表list1记录new得到的内存块,用链表list2记录delete释放的内存块,最后把这两个链表遍历,比较他的的值,值相同的去掉,剩下不同的值则是没有释放的内存。
 
0x00414BBC   fun(a);
0x00414BC1   
调用fun(a)时,a会入栈,然后会把返回地址(0x00414BC1)入栈。他们的内存是相邻的。所以我们可以把返回地址存储起来,我们就可以知道那段代码调用了这个函数。在VS2010中,调试的时候,右键,转到反汇编,定位到0x00414BC1处,就可以看到。
struct MenInfo
{
    unsigned int nNewCalAddress;//new函数调用地址。
    unsigned in nDeleteCallAddress;//delete函数调用地址。
    unsigned int nTotalSize;//内存总大小。我们需要额外的内存来存储一些信息,例如调用地址。
    unsigned int nUseSize;//使用大小。
};
list<void *> list1,
list<void *> list2;
//其实new只有一个参数,但是VS定义了new宏(大概是为了调试方便吧),所以变成了3个参数,
void *::operator new(unsigned int size, const char *file, int line)
{
    //参数入栈的顺序是从右到左,即最后入栈的是变量size
    ////函数返回的地址的地址等于最后入栈变量地址(这里是size)-4
    void **funAddr = (void **)(((int)&size) - 4);//函数返回地址的地址
    unsigned int nFunCallAddress = (*(int *)funAddr);//函数的返回地址
    void *pBuf = NULL;
    int nTotalSize = size + sizeof(MemInfo);//我们需要多分配一点内存来存储MenInfo
    try
    {
    pBuf = malloc(nTotalSize);
    }
    catch (...)
    {
    pBuf = NULL;
    return NULL;
    }
    MemInfo *pMemInfo = (MemInfo *)pBuf;
    pMemInfo->nNewCallAddress = nFunCallAddress;
    pMemInfo->nDeleteCallAddress = NULL;
    pMemInfo->nTotalSize = nTotalSize;
    pMemInfo->nUseSize = size;
    void *buffer = ((char *)pBuf + sizeof(MemInfo));
    memset(buffer, 0, size);
   //list1.push_back(buffer);
    return buffer;
}
void ::operator delete(void *buf)
{

  

    void **funAddr = (void **)(((int)&buf) - 4);//返回地址的地址
    unsigned int nFunCallAddress = (*(int *)funAddr);//得到返回地址
    MemInfo *pMemInfo = (MemInfo *)((char *)buf - sizeof(MemInfo));
    pMemInfo->nDeleteCallAddress = nFunCallAddress;

   

    memset(buf, 0, pMemInfo->nUseSize);
   //没有释放内存,我们需要内存块里面的信息(new函数返回地址,delete函数返回地址),所以只能用于调试。
    //list2.push_back(buf);
}
最后是要遍历list1和list2进行比较,就知道哪些内存没有释放,而且从内存块里我没可以知道new函数是在哪里调用的,可以快速定位到代码,从而进行查找原因
原文地址:https://www.cnblogs.com/dongc/p/5225138.html