内存运行时错误:我们在哪里删除此指针

HoK*_*y22 0 c++ pointers memory-leaks

在下面的四种方法中,我们应该做的更好.我们想在这里进行动态分配以避免错误的函数返回.但是,我们在哪里删除f?删除调用better()的函数?但在这种情况下再也没有了.

Foo *bad() {
  Foo f;
  return &f;
}

Foo &alsoBad() {
  Foo f;
  return f;
}

Foo mediocre() {
  Foo f;
  return f;
}

Foo * better() {
  Foo *f = new Foo;
  return f;
}
Run Code Online (Sandbox Code Playgroud)

And*_*owl 5

但在这种情况下再也没有了.

好吧,指针f超出范围,这是真的,但我们仍然返回指向同一对象的指针f.

因此,我们仍然有一个该对象的句柄,我们仍然可以调用delete返回的指针.事实上,你可以调用delete 任何时候创建一个对象后new.

你需要注意的是:

  • 你确实delete在某个时候为每个分配的对象调用new(否则你有内存泄漏);
  • 你不要delete为同一个对象多次调用,否则会得到未定义的行为;
  • 你没有取消引用一个指向已被破坏的对象的指针(即一个"悬空指针"),否则你会得到未定义的行为.

在一般情况下,手动内存管理,通过newdelete不鼓励在现代C++和所有权政策应通过实现智能指针来代替.要么...

在下面的四种方法中,我们应该做的更好

不完全是.事实上,我会说我们绝对不应该这样做better()- 虽然我们可以做一个better()修改版本来创建并返回一个智能指针而不是一个拥有的原始指针.

但是,功能mediocre()实际上非常好,这有两个原因:

  1. 首先,因为编译器很可能会忽略对复制构造函数的调用并执行(命名)返回值优化,从而导致没有运行时开销;
  2. 其次,正是因为有了C++ 11的移动语义,可能装备Foo移动的构造,使得通过值在大多数情况下,有效的,即使不进行省音返回.

此外,正如Zoidberg在评论中正确提到的那样,如果你真的不需要它们,就不应该使用指针.独特的所有权通常可以通过创建具有自动存储持续时间的对象(也就是"在堆栈上")来实现,并且移动语义使这种实践变得高效.只有在需要引用语义时才应创建指针.