当多个指针指向一个对象时如何删除该对象?

8

我被告知,如果我有多个指针指向同一个对象,我不能正常地删除它(使用delete关键字)。相反,我需要将指针设置为NULL或0。

假设我有:

ClassA* object = new ClassA();
ClassA* pointer1 = object;
ClassA* pointer2 = object;

那么,如果要 delete pointer1pointer2,我需要执行以下操作吗?

pointer1 = 0;
pointer2 = 0:

一旦我将其设置为NULL,我是否仍需要使用关键字delete?还是仅将其设置为0就足够了?


1
仅删除 pointer1pointer2 中的一个,然后将两个指针都设置为0,最好使用 std::shared_ptr - Mr.Anubis
@Kerrek,我不确定你的意思是什么?我只是在说“将指针设置为NULL并不等同于删除它。”并不清楚OP是否知道这一点。 - jrok
别跟我开玩笑了! :) - jrok
1
另一种看待这个问题的方式是:在C++中(与Java或Objective-C不同),编译器不会从您将指针设置为null这一事实中推断出任何信息。您需要显式地删除对象,并将引用设置为null是为了您程序自身的内部一致性/信息。 - Neil Coffey
7个回答

9
无论何时你使用new创建一个对象,都需要使用delete释放内存。
ClassA* object = new ClassA();

delete object; // Free's the memory you allocated.

将指针设置为NULL的目的是防止对无效指针进行解引用

object = NULL;

这样做是为了在尝试解引用之前进行测试:
if(object != NULL)
{
  object->SomeMethod(); // We can assume it's safe to use the pointer.
}

请注意,您可以从指向内存的任何指针中删除该内存。
ClassA* object = new ClassA();
ClassA* pointer1 = object;
ClassA* pointer2 = object;

delete pointer1; 

object、pointer1和pointer2现在都指向已经被释放的内存,除非它们将被重新定义,否则应全部设置为NULL


4
规则是:你必须调用和 new 调用次数相同的次数来调用 delete
因此,如果你只分配了内存一次,那么你也只需要释放一次内存。
你可以更好地使用 shared_ptr 来避免这种手动内存管理问题,其中智能指针本身将在没有指针指向其时释放内存。

2
你只需要确保在删除对象后不再使用它。指向该对象的指针并不重要,但你需要知道这些指针现在已经失效了。将它们设置为nullptr只是一种确保在使用它们时崩溃的方法;使用无效的指针可能会导致崩溃,也可能会导致难以追踪的问题。
然而,如果在删除对象时仍有“活动”指针指向它,这可能表明你的代码存在问题。通常情况下,当没有人需要对象时才会将其删除,这意味着应该没有指向它的指针或其他引用。当然,这不是一个硬性规则。

1
不行,你需要将其删除并设置为0,或者使用智能指针。

1

你必须使用delete,否则你将面临内存泄漏的问题。


0
代码使用new创建对象,应该使用delete销毁对象。只需要执行一次。其他指向该对象的指针并不重要,代码是否将这些指针设置为0也不重要。(除非你正在使用垃圾回收器,但你没有这样做)。将这些指针设置为0的唯一好处是,如果程序使用0作为表示无对象的标志。这是一个设计决策,无法从此处提供的信息中回答是否合适。

0

你并不能删除。但你也不应该这样做,因为删除一个已经被删除的对象会导致程序崩溃,你将看到glibc detected double free。所以最好的实践是

if(object){
   delete object;
   object = 0;
}

如果你不将它设为0NULL并在if语句中保护它,可能会出现双重删除。


这不是“最佳实践”。它过于冗长。delete object已经忽略了空指针,而将0写入0同样无害。 - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接