内存泄漏

内存泄漏一直是编程中不易察觉但可能会造成严重后果的大问题。在c/c++这种没有垃圾回收的语言系统中尤其明显。最近编程中遇到了一些相关的问题,网上没有查到满意的结果,特此整理收集。

PS:关于堆内存和栈内存的区别这里就不赘述了,网上有很多,理解起来也很容易


异常处理时的内存释放

先写结论:抛出异常时,栈内存会自动释放,而堆内存不会——这点与普通的函数退出一样。

按照网上的一些说法(虽然是关于线程的,但都有相似的问题),栈内存是在程序执行return语句时,编译器才会相应的释放该函数内新建的对象。所以之前一直怀疑,程序如果运行到抛出异常的节点而退出,(因为没有执行return)是否就无法顺利释放相应内存。于是写了下面一段代码测试:

class myclass{
    int a;
public:
    myclass(int a):a(a){};
    int getNum(){ return a;};
    ~myclass(){
        a=0;
        cout<<"destruction fun"<<endl;
    };
};

void test(myclass *&p){
    myclass m(7);
    p=&m;
    throw exception();
    p->getNum();
}


int main(int argc,char** argv){
    myclass* p;
    try{
        test(p);
    }
    catch (exception) {
        cout<<p->getNum()<<endl;
    }
    return 0;
}

程序运行的结果是

destruction fun
0

可以发现,虽然子函数抛出异常回到主函数中了,但子函数仍然执行了myclass的析构函数。值得注意的是,通过p指针仍能访问这个理应被析构了的对象m并得到正确的结果。但这并不说明m没有被析构,只是原先记录m数据的内存还没有被新数据刷新覆盖而已

如果我们调整一下test函数如下,尝试把新对象建立在堆内存上:

void test(myclass *&p){
    p=new myclass(7);
    throw exception();
    p->getNum();
}

其他程序不变,最后的结果则变成了

7

可以发现,析构函数没有被调用(想想也不太可能对吧),这里就会造成内存泄漏了。


–待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值