如何解决下面的内存泄露问题?

Gallen 2001-07-10 11:05:34
CODE:
class A
{
private:
int m_nCount;
};

A &Test()
{
A *x = new A;
return *x;
}

Qustion:
要求:Test一定返回A&, 为了效率尽量少产生临时对象.
1. return *x, 是否回产生临时对象?
2. 上面有MEMORY LEAK, 如果我写成这样:
A &Test()
{
A x;
return A;
}
就不会有问题, 那么这样一来, 我返回A&岂不是和返回A一样了吗?

归根到底, 我对引用和指针的区别不是很清楚, 请高手指点.
...全文
193 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
darkay 2001-07-10
  • 打赏
  • 举报
回复
不能一概而论的哦,君不见iostream大都返回引用的哦!
to Gallen:mA应该不是在stack中吧!它就是new出来的那个对象啊,应该是在heap中才是啊!
既然是这样的话,那个heap里面的对象肯定要delete才行啦!是不是?
Gallen 2001-07-10
  • 打赏
  • 举报
回复

混乱: 如果我只有一个接口声明: A &Test(); 而不知道它是如何实现的(返回的东西是new出的还是一个static的对象), 我们就不知道是否应该"delete &a". 从而这种写法使程序的藕合度增大, 而根源就在于我们要返回一个对象的引用.
结论: 最好不要返回对象引用.
liu_feng_fly 2001-07-10
  • 打赏
  • 举报
回复
试试delete &x;呢?
Gallen 2001-07-10
  • 打赏
  • 举报
回复
To littleme741:
有这样的写法吗? "delete &mA", mA本身就是在stack中, 为什么还要你去delete呢?
我试了一下你的写法, 确实没有内存泄露, 但请解释为什么要"delete &mA"?

To liu_feng_fly:
不错, 编译器改写成这样, 但 "A *x = new A;" 一句中的"new"何时delete呢?
liu_feng_fly 2001-07-10
  • 打赏
  • 举报
回复
呵呵,建议看看<深入探索c++对象模型>那里边是这样说的
其实你写
A &Test()
{
A *x = new A;
return *x;
}
编译器还是会把他处理成这样的函数
void test(A& __result)
{
A*x=new A;
__result=x;
}

isdom 2001-07-10
  • 打赏
  • 举报
回复
class A
{
private:
int m_nCount;
};

A &Test()
{
A *x = new A;
return *x;
}

假设:
A &aa = Test();
在不需要 aa 时, delete &aa, 就这样呀, 有什么不行的, 呵呵, 不过难看了一点
littleme741 2001-07-10
  • 打赏
  • 举报
回复
你采用第二种方法编译系统肯定会出现一个警告,告诉你你把一个局部变量做为引用返回了,事实上这样就存在隐患,因为该块内存(放在stack中的)会被操作系统做为它用,这样就相当于你返回的这个对象的空间内容被该写了。这是非常危险的,当然如果把定义
A x;
该成:
static A x;
要好一点。

但我是强烈建议你用第一种方法。第一种方法的要点是在调用Test函数的函数中不要忘记释放该对象。比如:
void myUsing()
{
A mA;
mA=Test();
//这里可以对A进行各种处理
delete &mA;//这一句很重要,释放空间,防止内存leak.
}
Gallen 2001-07-10
  • 打赏
  • 举报
回复
to pgfun:
这样做是没有问题的, 而且"A* Test()" 会在接口上更清晰一些, 但我想一定要返回引用.
pgfun 2001-07-10
  • 打赏
  • 举报
回复
void Test(A* v)
{
return;
}

这样好像容易一点.

Gallen 2001-07-10
  • 打赏
  • 举报
回复
谢谢各位的答复

A &mA = Test();
delete &mA;
这种写法虽然正确,但很让人不理解.

谢谢
flagfly 2001-07-10
  • 打赏
  • 举报
回复
有道理
liu_feng_fly 2001-07-10
  • 打赏
  • 举报
回复
to:Gallen()应该是这样的,CODE1:的在stack中,CODE2就不一定了,极其有可能在heap中
littleme741 2001-07-10
  • 打赏
  • 举报
回复
to Gallen():
原则上说,你说的很对。第一段代码通过生成一个中间变量的对象,然后把对象复制给mA,在删除中间对象,然后完成操作。
而第二段代码只能通过静态对象变量或者new新的对象变量返回,前者需要delete,后者是由编译器负责释放其空间。

Gallen 2001-07-10
  • 打赏
  • 举报
回复

以下两段代码有什么区别?
CODE1:
A mA;
mA = Test();

CODE2:
A &mA = Test();

是否可以说: CODE1中的mA一定是在stack中, 而CODE2中的就不一定了, 要看Test()的实现?
littleme741 2001-07-10
  • 打赏
  • 举报
回复
to Gallen():
delete &mA中的mA就是在Test()中A *x=new A中的那个x,你说那个x是在heap中还是在stack中的?参看darkay(火凤凰)的说法。

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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