如果一个函数在申请了堆内存,并且这个函数可能在多处返回,如何处理堆内存的释放?

鸟类学 2016-06-01 02:16:13
加精
如果一个函数在申请了堆内存,并且这个函数可能在多处返回,如何处理堆内存的释放?
我遇到的问题如下(伪代码):

int funA()
{
unsigned char *pHeap = funB();//funB函数内部申请的堆内存,返回给pHeap,并且申请的内存是一个unsinged char的数组

if(....) return x;
if(....) return y;
//........多种情况都导致funA()返回
}

如果在每次返回的代码前加释放的语句,感觉有些难看。
如果用智能指针 感觉好像有问题,而且这个智能不是维护的一个类对象,我用代码测试了shared_ptr<unsigned char> pSharedHeap,跟踪一下智能指针 的释放,它最后只是用delete 来释放内存,而不是delete[]。这样的话,也是会内存泄漏吧。
我该怎么处理这个问题?
希望论坛的朋友帮帮忙,给些建议。谢谢。
...全文
3437 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
yunshouhu 2018-07-04
  • 打赏
  • 举报
回复
引用 39楼ccnyou 的回复:
[quote=引用 33 楼 haitao_J 的回复:] 这是我用的解决方案 int funA() { int nRet=0; do { if(....) {nRet = 1;break;} if(....) {nRet = 2;break;} }while(FALSE); //释放 return nRet; }
用 do while(false) 实现了 goto 的语法。而且这种情况如果里面再有个for循环,就更麻烦了,for里面遇到函数失败了得又找个语法糖让它直接break到下面的while那里,累不累呀?[/quote]内部再一个for循环失败,直接再break出来即可,最终会走到最后的清理操作。
Davidskoy 2016-06-20
  • 打赏
  • 举报
回复
不错不错,学到了。大神们,真牛!
qq_35346160 2016-06-17
  • 打赏
  • 举报
回复
他个人问题有关虽然有告诉她
XHL001188 2016-06-16
  • 打赏
  • 举报
回复
你这个需求不需要 shared_ptr, std::unique_ptr<unsigned char[]> pUniqueHeap; 就可以
月xxxxx 2016-06-16
  • 打赏
  • 举报
回复
1. 建议少用智能指针,如果要用,自己可以先写一个简单的,了解原因再用 2. 建议尽量用引用代替指针,能加const 就加cosnt 3. RAII原则,让C++自己管理内存。要求效率的,重写new操作符,并使用内存池 4. 如果是模板指针,考虑使用句柄管理器和单例模式或工厂模式 接分,祝 好运
bravery36 2016-06-12
  • 打赏
  • 举报
回复
引用 41 楼 z8323664 的回复:
至于用if, switch case 来判断, 你们考虑过异常情况吗?
异常最麻烦的地方是没办法全部捕获,c++也没有像finally这样便利的语法,所以就算catch了还是有可能没释放,这个时候只需要微笑就行了。
z8323664 2016-06-12
  • 打赏
  • 举报
回复
至于用if, switch case 来判断, 你们考虑过异常情况吗?
z8323664 2016-06-12
  • 打赏
  • 举报
回复
char *inBuffer = malloc(xxx);
int funA(inBuffer);
free(inBuffer);
ccnyou 2016-06-10
  • 打赏
  • 举报
回复
引用 33 楼 haitao_J 的回复:
这是我用的解决方案 int funA() { int nRet=0; do { if(....) {nRet = 1;break;} if(....) {nRet = 2;break;} }while(FALSE); //释放 return nRet; }
用 do while(false) 实现了 goto 的语法。而且这种情况如果里面再有个for循环,就更麻烦了,for里面遇到函数失败了得又找个语法糖让它直接break到下面的while那里,累不累呀?
ccnyou 2016-06-10
  • 打赏
  • 举报
回复
引用 32 楼 ljheee 的回复:
使用容器,可以实现吗,返回的,都先加入容器。
这种情况都是,已有的函数返回的明确是指针了,要在外面包容器也行,不过那还不如用智能指针呢。
cattpon 2016-06-09
  • 打赏
  • 举报
回复
learning~
mike.jiang 2016-06-08
  • 打赏
  • 举报
回复
xigua1102 2016-06-08
  • 打赏
  • 举报
回复
引用 22 楼 ccnyou 的回复:
前一家公司都是这种画风,虽然用了goto感觉很low,实际简洁高效,不含防腐剂和语法糖

int funA()
{
    int result = 0;
    unsigned char *pHeap = funB();//funB函数内部申请的堆内存,返回给pHeap,并且申请的内存是一个unsinged char的数组

    if(....) 
    {
        result = x;
        goto Exit0;
    }
    
    if(....)
    {
        result = y;
        goto Exit0;
    }
    //........多种情况都导致funA()返回
      
Exit0:
    if(pHeap) {
        delete pHeap;
    }
    
    return result;
}

我觉得goto并不low,实际上goto用于处理这种问题是非常简洁高效的,到处都在说慎用goto的主要原因是怕有人乱用goto让代码乱跳。个人意见
cattpon 2016-06-08
  • 打赏
  • 举报
回复
这个问题也困扰我很久啊~
haitao_J 2016-06-08
  • 打赏
  • 举报
回复
这是我用的解决方案 int funA() { int nRet=0; do { if(....) {nRet = 1;break;} if(....) {nRet = 2;break;} }while(FALSE); //释放 return nRet; }
ljheee 2016-06-08
  • 打赏
  • 举报
回复
使用容器,可以实现吗,返回的,都先加入容器。
f1234560hzx 2016-06-08
  • 打赏
  • 举报
回复
引用 22 楼 ccnyou 的回复:
前一家公司都是这种画风,虽然用了goto感觉很low,实际简洁高效,不含防腐剂和语法糖

int funA()
{
    int result = 0;
    unsigned char *pHeap = funB();//funB函数内部申请的堆内存,返回给pHeap,并且申请的内存是一个unsinged char的数组

    if(....) 
    {
        result = x;
        goto Exit0;
    }
    
    if(....)
    {
        result = y;
        goto Exit0;
    }
    //........多种情况都导致funA()返回
      
Exit0:
    if(pHeap) {
        delete pHeap;
    }
    
    return result;
}

简单有效
ID870177103 2016-06-07
  • 打赏
  • 举报
回复
1。智能指针又不是只有share_ptr,unique_ptr可以管理任意资源 2。windows上有__finally可用 3。尽量不用手动分配内存,封装个堆数组没那么难
qulei616 2016-06-07
  • 打赏
  • 举报
回复
不懂来学习下
cattpon 2016-06-07
  • 打赏
  • 举报
回复
引用 1 楼 jianwen0529 的回复:
1. 增加一个临时变量为返回值,判断语句只是赋值 在函数结尾返回,同时在之前delete 2. 延迟申请内存,在需要的地方才申请 3. 函数参数传入一个地址块,该地址块是unsigned char *pHeap = funB() 在函数调用处维护和申请内存 4. 改为栈内存 或者使用vector等容器存放 自己看来哪个适合
正解~
加载更多回复(16)

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧