我有关于c ++内存分配和释放的问题。 情况如下: 我有一个方法foo,它分配内存,然后返回该对象:
Object foo () {
Object *a = new Object();
// Do something with this object...
return *a;
}
和另一个使用此返回对象的方法:
void bar () {
Object a = foo();
// Do something..
}
我的问题是,我应该在何时释放我分配的内存?当我从方法foo返回时,方法栏是否在其堆栈上获得该对象的副本,或者它是否可以访问内存中的某个对象?
谢谢! 巴特
答案 0 :(得分:5)
您无法释放该对象。它丢了。这是一个内存泄漏。你永远不应该(动态地)分配它。您的代码应如下所示:
Object foo () {
Object a;
// Do something with this object...
return a;
}
当我从方法foo返回时,方法栏是否获得了副本 该对象在其堆栈上,或者是否可以访问该对象 在记忆的某个地方?
它是仍然存在的无法访问的对象的副本。
答案 1 :(得分:3)
因为你没有返回你分配的对象而是它的副本而泄漏了内存。 最简单的解决方案是不要使用新的
Object foo () {
Object a;
return a;
}
如果你确实需要堆上的对象,例如如果它是一个多态对象并且你返回一个指向基类的指针,那么它看起来像是
Base* foo () {
Base *a = new Derived();
return a;
}
但这段代码远非好。这也不例外,它可能导致内存泄漏。因此,您几乎总是使用智能指针(如std :: unique_ptr(仅限c ++ 11),std :: auto_ptr或boost :: shared_ptr)来换行。
std::unique_ptr<Base> foo () {
std::unique_ptr<Base> a(new Derived();
return a;
}
答案 2 :(得分:1)
用new
分配内存告诉编译器:“别担心,我知道我在做什么:这个对象将由我控制”。这意味着,编译器确实不会担心它而且你负责。最好的解决方案是:除非你真的知道自己在做什么,否则不要这样做。请注意,我很确定我知道自己在做什么,但我通常不会使用new
,因为没有必要!
在您的示例中,您要使用
Object foo() {
Object a;
// do something
return a;
}
从概念上讲,对象是在堆栈上创建的,并在返回时复制。复制完成后,本地对象将被销毁。在实践中,这很少发生真正的事情:由于本地对象在复制后立即被销毁,编译器可以自由地执行您通常想要的操作,即:对象a
不会被复制或销毁但实际上直接返回。但是,这应该会产生相同的结果(如果没有,那么你的类会在某处被破坏)。
答案 3 :(得分:0)
在这个例子中你不能。由于调用函数永远不会知道创建动态对象的位置(甚至意识到)。 如果你要使用引用(或指针),那么调用者在完成使用它时就会释放它。