4

所以,这是我解释这个问题的例子

void * p1;
int * p2, * p3;

p2 = new int;
p1 = p2;
p3 = (int *) p1;

要释放内存,以下 3 行是否彼此等效?

delete p2;
delete p3;
delete (int *) p1;

我使用它的原因是我想在函数之间传递一个指针而不知道它的类型,例如我定义一个 void 指针并通过调用其他函数来更改它的值,如下所示:

void * p1;
func1(p1); //in this function, p2 = new int and  p1 is assigned as p1 = p2;
func2(p1); //in this function, p1 is assigned to another pointer: int * p3 = (int *)p1;

然后,我调用了 func3 来释放内存

func3(p1); //delete int * p1

调用 func3 后,我是否必须再处理 func1 中的 p2 ?

谢谢!

4

4 回答 4

8

是的,所有 3 deletes 都是等价的。需要注意的是,在发布的示例中,所有 3 个指针都指向同一事物。这意味着,如果您delete是其中之一,则不应delete使用其他人,因为他们指向的内存已被释放。

如果你确实尝试了delete一些已经发布的东西,你会唤起未定义的行为。如果你很幸运,你的程序会崩溃,但任何事情都可能发生。

于 2012-11-06T21:00:55.417 回答
7

该问题包含一个误解:您不删除指针。您删除他们指向的内容。

而且您不能多次删除同一事物。

想想三个人用手指指向同一个盒子。其中一个说“扔掉”。一旦它被抛出,他们将保持手指仍然指向同一个方向指向一个空白空间。没有什么可以扔掉的了。

于 2012-11-06T21:08:03.807 回答
3

您只有一个分配,因此只需要删除一个。你有三个项目可以让你找到那个内存(你的指针),所以任何一个都可以将它释放回操作系统。一旦释放回 O/S,请注意不要使用任何旧指针,因为它们仍然保存您现在释放的内存的旧地址。去使用释放的内存是不好的。

于 2012-11-06T21:01:01.517 回答
0

是的,这三个都是等价的。在调用 delete 之后,您唯一想做的就是将指针设置为 nullptr,这样您就可以知道它们不再有效:

p1 = nullptr ;
p2 = nullptr ;
p3 = nullptr ;

请记住,指针指向内存。当你这样做时:

p2 = new int;

您是在说“向我声明一些新内存并将其地址保存在 p2 中”。现在您可以使用 p2 访问该内存。

当你这样做时:

p1 = p2;

您是在说“我希望 p1 指向 p2 指向的同一内存”。您现在有两个指向同一内存的指针。

如果您对任何一个指针调用 delete,它将删除该内存,并且所有这些指针现在都将指向同一个已释放的内存(即它们现在无效)。

释放内存后通常要做的事情是让指针变量超出范围或将它们设置为 nullptr 以便您可以检测它们不再有效。

于 2012-11-07T11:56:20.013 回答