如何删除指针及其指向的对象?
下面的代码会删除对象吗?
Object *apple;
apple = new Object();
delete apple;
Run Code Online (Sandbox Code Playgroud)
如果指针没有删除,并且超出范围会发生什么?
Object *apple;
apple = new Object();
Run Code Online (Sandbox Code Playgroud)
这可能是一个非常基本的问题,但我来自Java.
小智 12
您的第一个代码段确实删除了该对象.指针本身是在堆栈上分配的局部变量.一旦超出范围,它将被解除分配.
这提出了第二点 - 如果在释放在堆上分配的对象之前指针超出范围,您将永远无法释放它,并且将发生内存泄漏.
希望这可以帮助.
您好,欢迎来到 C++ 土地!你会喜欢你有多讨厌它(或类似的东西)。C++ 虽然在未经训练的人看来与 java 很相似,但实际上在语义上有很大不同。让我们看看这些语义在 C++ 中如何针对您的问题发挥作用。首先我们来上课:
class Foo {
public:
Foo() { std::cout << "In constructor\n"; }
~Foo() { std::cout << "In destructor\n"; }
};
Run Code Online (Sandbox Code Playgroud)
这里的 Foo 只是您可能想要使用的任何类的代表。让我们看看当我们创建并使用一个普通的 Foo 对象时会发生什么:
{
Foo bar;
do_stuff(bar);
}
Run Code Online (Sandbox Code Playgroud)
如果我们运行如下所示的代码,我们会看到:
In constructor
In destructor
Run Code Online (Sandbox Code Playgroud)
这是因为,当创建一个对象时,它是使用构造函数构造的。当它超出范围时,将调用析构函数(在我们的代码中为~Foo)来解构(或销毁)该对象。这实际上是 C++ 中相当常见且强大的功能(称为RAII,而不是向系统返回内存的其他形式,例如垃圾收集)。有了这些新知识,让我们看看当我们使用指向 Foo 的指针时会发生什么:
{
Foo *bar = new Foo();
some_more_stuff(bar);
}
Run Code Online (Sandbox Code Playgroud)
我们会看到这里发生的情况:
In constructor
Run Code Online (Sandbox Code Playgroud)
这是因为指针的分配方式与变量的分配方式不同。按照分配指针的方式,它们实际上通常不会超出范围,但它们的内容会超出范围。这称为悬空指针。要获得更好的示例,请看一下:
#include <iostream>
int* get_int() {
int qux = 42;
int *foo = &qux;
return foo;
}
int main() {
int *qazal = get_int();
std::cout << *qazal;
}
Run Code Online (Sandbox Code Playgroud)
感谢现代操作系统,当程序完成时,该内存仍然会被返回,但不会在程序运行期间返回。如果我们通过delete删除指针(在它创建的同一范围内),那么该内存实际上将在那时返回给操作系统。