释放函数中的内存

时间:2016-03-14 20:29:57

标签: c++ memory-management

前几天,当我意识到我没有为我的功能释放内存时,我正要问一个相当简单的初学者问题我正在研究的c ++函数。这似乎永远不会在这里结束。

这似乎是一个常见的问题,但我无法在c ++的理解水平上找到任何东西

如何在此代码中正确释放内存

#include <iostream>

class thing{
    public:
    int a;
    };

thing makeThing(){
    thing *t = new thing;
    t -> a = 5;
    return *t;
    }

int main(){
    thing thing1 = makeThing();
    std::cout << "a: " << thing1.a << std::endl; 
    return 0;
    }

据我所知,在函数终止后我无法释放它。 我试过这个:

delete &thing1;

但是基于核心转储,我认为不是这样做的。

4 个答案:

答案 0 :(得分:3)

有时,释放内存的最简单方法是不要将其分配给:

thing makeThing(){
    thing t;
    t.a = 5;
    return t;
}

您尝试做的事情不起作用的原因是,当您有:

delete &thing1;

这是您本地对象的地址......这不是您实际分配的地址。那个被复制到你的,现在你无法访问它。

如果您想分配thing,则需要直接返回指针。最好以某种方式包裹:

std::unique_ptr<thing> makeThing() {
    std::unique_ptr<thing> t(new thing);
    t->a = 5;
    return t;
}

答案 1 :(得分:3)

由于您按值返回,这意味着您将返回该对象的副本。在new things创建的原始对象在函数返回后无法到达(无论如何都不可靠)。

你可以返回一个指针:

thing* makeThing(){
  thing *t = new thing;
  t -> a = 5;
  return t;
}

删除它。

但是你应该真的只返回一个对象,在这种情况下甚至不用new分配任何东西。

答案 2 :(得分:1)

thing makeThing(){
    thing *t = new thing;
    t -> a = 5;
    return *t;
    }

导致即时内存泄漏。 t返回后,makeThing()变量将超出范围,并且永远不会释放分配的内存,也无法使用适当的delete语句进行发布。

有新创建的t返回的副本。

要修复它,只需创建一个局部变量并重新复制:

thing makeThing(){
    thing t;
    t.a = 5;
    return t;
}

答案 3 :(得分:0)

如果您真的想使用new,这是正确的方法。此代码是C ++ 11,因此您可能需要打开某个选项,如果它不是您正在使用的编译器中的默认选项。我习惯使用C ++ 11,因为该语言版本的改进确实值得。

#include <iostream>
#include <memory>
#include <ostream>

class thing {
public:
  int a;
};

std::ostream& operator<<(std::ostream& os, const thing& t) {
  os << t.a;
  return os;
}

std::unique_ptr<thing> makeThing() {
  std::unique_ptr<thing> t(new thing); 
  t->a = 5;
  return std::move(t);
}

int main() {
  auto thing1 = makeThing();
  std::cout << "a: " << *thing1 << std::endl; 
  return 0;
}

但实际上,如果你想要做的就是创建一个对象,就不需要在堆上分配它。你可以像下面的代码那样做。请注意,该对象是在不使用new的情况下创建的。从makeThing()返回时复制该对象,并且编译器在执行此操作时使用class thing的默认复制构造函数(我没有替换)。

#include <iostream>
#include <ostream>

thing makeThing() {
  thing t;
  t.a = 5;
  return t;
}

int main() {
  auto thing1 = makeThing();
  std::cout << "a: " << thing1 << std::endl; 
  return 0;
}

ostream插入器不需要更改,所以我省略了它。类定义也一样。