返回后的C ++内存释放

时间:2012-03-03 21:49:21

标签: c++ memory-leaks memory-management

我有关于c ++内存分配和释放的问题。 情况如下: 我有一个方法foo,它分配内存,然后返回该对象:

Object foo () {
  Object *a = new Object();
  // Do something with this object...
  return *a;
}

和另一个使用此返回对象的方法:

void bar () {
  Object a = foo();
  // Do something..
}

我的问题是,我应该在何时释放我分配的内存?当我从方法foo返回时,方法栏是否在其堆栈上获得该对象的副本,或者它是否可以访问内存中的某个对象?

谢谢! 巴特

4 个答案:

答案 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)

在这个例子中你不能。由于调用函数永远不会知道创建动态对象的位置(甚至意识到)。 如果你要使用引用(或指针),那么调用者在完成使用它时就会释放它。