在C++中,为什么当对象的指针超出范围时不能释放对象?

问题描述 投票:0回答:2

假设我有一个方法,然后

new
方法内有一个对象:

void MyMethod() {
  Obj* p = new Obj();
}

当函数结束时,指针将被删除,因为它超出了范围,如果我没有返回

p
指针,那就意味着没有这个
Obj
对象的引用,为什么编译器不能这样做为我们删除对象?

因此,如果人们忘记这样做,就不会出现“内存泄漏”。

c++ pointers
2个回答
1
投票

可以用

std::unique_ptr
!原始指针并不适合现代 C++ 中的日常使用,您需要这样:

#include <memory>

void MyMethod() {
  std::unique_ptr<Obj> p = std::make_unique<Obj>();
   // no leak!
}

或者你也可以这样做

Obj p;
但我猜你知道这一点。


0
投票

在编译时确定指针是否超出范围非常困难。

假设你有这样的代码:

void bar(Obj* obj); //we do not know what this method does

int MyMethod() {
  Obj* obj = new Obj();
  bar(obj);
}

可以删除

obj
末尾的
MyMethod
吗?答案是否定的,因为
bar()
可能仍然会使用它。例如,
bar
可能如下所示:

void* someGlobalVariable;

void bar(Obj* obj) {
  someGlobalVariable = (void*) obj;
}

那么

MyMethod
可能不会删除该对象,因为它从
someGlobalVariable
开始仍在使用中。
bar()
也可能不会删除该对象,因为您不希望方法在您不期望的情况下随机释放传递给它们的内存。所以编译器在这里帮不了你,你需要自己管理内存。

一般来说,我们希望最终释放我们分配的所有内存。由于编译器无法为我们执行此操作(至少并非总是如此),因此我们需要手动执行此操作。现在,我们可以设计一个编译器,它对于何时自动插入删除指针的代码有一些规则。

但是这样的编译器在实践中使用起来会很麻烦,因为你总是需要记住编译器何时为你删除内存的规则,而不是你需要自己删除内存的规则。如果你让编译器变得更聪明,你就会让现有的程序出错。因此,C 的设计者选择了一致的选项“你必须始终释放自己分配的所有内存”。

© www.soinside.com 2019 - 2024. All rights reserved.