c++ - 内存运行时错误 : where do we delete this pointer

标签 c++ pointers memory-leaks

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

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;
}

最佳答案

But there is no f any more in that case.

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

因此,我们仍然拥有该对象的句柄,并且我们仍然可以在返回的指针上调用 delete。事实上,您可以在使用 new 创建对象后随时调用delete

您需要注意的是:

  • 你确实在某个时候为每个分配了 new 的对象调用了 delete(否则你有内存泄漏);
  • 不要为同一个对象多次调用delete,否则会出现未定义的行为;
  • 您不能取消引用指向已销毁对象的指针(即“悬挂指针”),否则您会得到未定义的行为。

一般来说,在现代 C++ 中不鼓励通过 newdelete 进行手动内存管理,所有权策略应该通过智能指针来实现. 或者...

In the four method below, only better is what we should do

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

然而,mediocre() 函数实际上相当不错,原因有二:

  1. 首先因为编译器很可能会省略对复制构造函数的调用并执行(Named) Return Value optimization。 ,因此不会产生运行时开销;
  2. 其次,由于 C++11 的移动语义,有可能 为 Foo 配备一个按值返回的移动构造函数 在大多数情况下即使不执行省略也是有效的。

此外,作为Zoidberg在评论中正确提到,如果你真的不需要它们,你根本不应该使用它们。唯一所有权通常可以通过创建具有自动存储持续时间(又名“在堆栈上”)的对象来实现,移动语义使这种做法变得高效。只应创建指针 when you need reference semantics .

关于c++ - 内存运行时错误 : where do we delete this pointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15713611/

相关文章:

C++:std::map的微小内存泄漏

ios - 如何使用 ARC 释放 NSMutableArray 中的对象?

c++ - 寻找符号依赖的起源

android - Cocos2d-x 应用程序无法为 Android 编译

c++ - 如何通过引用或指针将 `int` 和 `unsigned int` 成员传递给同一个函数?

c++ - 这个数组声明有什么问题?

debugging - 将 DLL 固定在内存中(增加引用计数)

c++ - boost::interprocess 互斥与 boost 线程互斥

c++ - 如何只读取文件.txt 中的数字?

c - 使用指针的段错误 (SIGSEGV)