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

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一样了吗?

归根到底, 我对引用和指针的区别不是很清楚, 请高手指点.
...全文
127 点赞 收藏 15
写回复
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(火凤凰)的说法。
回复 点赞
发动态
发帖子
VC/MFC
创建于2007-09-28

7894

社区成员

42.1w+

社区内容

VC/MFC相关问题讨论
社区公告
暂无公告