throw try...catch...内存泄漏问题

来源:互联网 发布:网络金融牌照 编辑:程序博客网 时间:2024/05/23 01:11
我编了一个服务器程序,多线程,在测试的时候没有发现内存泄漏,但是在实际应用中,发现较长一段时间后,程序占用了大量的虚拟内存。最近发现是在处理throw try catch异常事务时出现的,通过简单的编程测试可以证实throw try catch语句的内存泄漏问题,求教高手有什么好的解决方案?
   测试例程如下:
对于throw    try...catch...语句,存在内存泄漏问题:如果是使用堆栈内存,不存在内存泄漏问题,但如果是使用堆内存,就存在内存泄漏问题。
测试例程
#include <iostream.h>
#include <windows.h>
#include <string>
#include <malloc.h>
class AA
{
    private:
    char * buff;
    public:
        AA():buff(NULL){}
        ~AA()
        {
            if(buff!=NULL)
                delete buff;
        }
        void Init(){buff = new char[10240];}
};
void test(void)
{    //会产生内存泄漏,因为aa.Init()中分配了堆内存,在throw时内存来不及释放。
    AA aa;
    aa.Init();
    throw "test_error ";
    return ;
}
void test2(void)
{    //不会产生内存泄漏,因为buff使用的是堆栈内存,在函数结束时清理堆栈将自动清理堆栈
    char buff[10240];
    throw "test_error2";
    return ;
}
void test3(void)
{    //会产生内存泄漏,因为new中分配了堆内存,在throw时内存来不及释放。    
    char *buff;
    buff = new char[10240];
    throw "test_error2";
    delete buff;
    return;
}
void test4(void)
{    //会产生内存泄漏,因为aa=".."中分配了堆内存,在throw时内存来不及释放。(证明标准的C++类也存在同样的内存泄漏问题。)
    std::string aa;
    aa = "kasdfasdfasdfaksldfjas;lkasdjg;laksdjg;alskdjgf;alskdjf;alksjd;kgjas;dlkjfalskjdhlkasjghlaksdjhglaskdjgfashdkjlg";
    throw "test_error ";
    return ;
}
void test5(void)
{    //不会产生内存泄漏,因为_allca使用的是堆栈内存,在函数结束时清理堆栈将自动清理堆栈,所以该内存的有效使用范围只在本函数内,而且不能使用free释放内存。
    char * buff;
    buff = (char *)_alloca(1024);
    throw "test_error5";
    return ;
}
int main(void)
{
    for(int i=0;i<10000;i++)
    {
        try{
            test5();
        }
        catch(const char *ser)
        {
        }
        cout << i << "\r";
        Sleep(10);
    }
    return 0;    
}

如果需求保证内存泄漏问题,需要管理内存链表,在catch事务处理中进行内存检查和回收。但是在多线程程序中比较难以处理。
如:
class  bb

private:
    MyMemoryList *p;
public:
    bb();    --> p->Add(this);    // 增加到管理链表
    ~bb(); --> p->Del(this); // 从链表中删除,如果碰到throw来不及删除,将在p中留下记录。


另一种方法是在碰到throw时,把因该清除的内存清理干净。这样做的难度比较大。