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/archive/2013/03/24/5225138.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++内存泄露

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/81811

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午8:15
下一篇 2023年2月9日 下午8:15

相关推荐