在下面的四种方法中,只有更好才是我们应该做的。我们想在这里动态分配以避免错误的函数返回。但是,我们在哪里删除 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++ 中不鼓励通过 new
和 delete
进行手动内存管理,所有权策略应该通过智能指针来实现. 或者...
In the four method below, only better is what we should do
不完全是。事实上,我会说我们绝对不应该做 better()
- 尽管我们可以做一个版本的 better()
修改来创建和返回智能指针而不是拥有原始指针。
然而,mediocre()
函数实际上相当不错,原因有二:
- 首先因为编译器很可能会省略对复制构造函数的调用并执行(Named) Return Value optimization。 ,因此不会产生运行时开销;
- 其次,由于 C++11 的移动语义,有可能
为
Foo
配备一个按值返回的移动构造函数 在大多数情况下即使不执行省略也是有效的。
此外,作为Zoidberg在评论中正确提到,如果你真的不需要它们,你根本不应该使用它们。唯一所有权通常可以通过创建具有自动存储持续时间(又名“在堆栈上”)的对象来实现,移动语义使这种做法变得高效。只应创建指针 when you need reference semantics .
关于c++ - 内存运行时错误 : where do we delete this pointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15713611/