我有以下代码
MyObject * func1() {
MyObject * obj = new MyObject();
// lots of stuff here
return obj;
}
MyObject func2() {
MyObject * obj = func1();
// even more stuff here
return *obj;
}
void main() {
MyObject obj = func2()
}
当我从here得到它时,这段代码正在泄露。请问:
MyObject * func1() {
MyObject * obj = new MyObject();
// lots of stuff here
return obj;
}
MyObject func2() {
MyObject * obj = func1();
// even more stuff here
MyObject obj_r(*obj);
delete obj;
return obj_r;
}
void main() {
MyObject obj = func2()
}
解决问题?或者还有其他一些不错的解决方案吗?
b4中的:不,我不能从头开始引用它,因为func1()在某些情况下会返回NULL。
upd:添加了一些评论,以便人们不认为我是愚蠢的
答案 0 :(得分:4)
更优雅的解决方案(更“正确”)将是使用智能 指针:
MyObject func2()
{
return *std::auto_ptr<MyObject>(func1());
}
(使用更现代的编译器,使用std::unique_ptr
。或者如果您正在使用
提升,你也可以使用boost::scoped_ptr
。)
我说更“正确”,因为如果是MyObject
的复制构造函数
抛出一个异常,这个解决方案仍然会删除对象,在哪里
因为你会泄漏。
答案 1 :(得分:1)
是的,这将解决内存泄漏。
一般来说,这不是一个非常好的模式。但后来我不确定你在这里想要达到的目标!
答案 2 :(得分:1)
避免内存泄漏的最佳方法是使用智能指针:
#include <memory>
MyObject func2() {
std::unique_ptr<MyObject> obj(func1());
// stuff here
return *obj;
}
int main() {
MyObject obj = func2();
}
这与您的解决方案几乎相同,但修复了在复制对象或执行“内容”时抛出异常时您的内存泄漏。如果您不使用C ++ 11,请使用auto_ptr
而不是unique_ptr
。
答案 3 :(得分:0)
只需将func2()
更改为:
MyObject func2() { return MyObject(); }
在您的情况下,动态分配完全没用。
答案 4 :(得分:0)
是的,您的第二个解决方案将以更多副本为代价来解决问题。
我的问题是:为什么要在堆上分配一个对象(使用new)只是为了将它复制到堆栈分配的对象,然后立即将其删除。你为什么不在开始时只在堆栈上创建它?
您可以按如下方式编写:
void main() {
MyObject obj;
}
最后你会得到完全相同的结果。而且它会简单得多!
答案 5 :(得分:0)
恕我直言,最好的方法是删除func1中的对象,如果它必须删除NULL。 在func2中,如果我们收到空指针,我们就不能以任何方式取消引用它。
答案 6 :(得分:0)
如果您不确定func1
是否会返回有效对象,而不是返回指针,boost::optional
可能是合适的 - 这会让func2
检查{是否{ {1}}返回了一些有效的内容,而不必动态分配任何内容。