为什么不删除将指针设置为NULL?

时间:2009-04-01 07:48:50

标签: c++ memory-management delete-operator

我总是想知道为什么在 delete 之后将指针自动设置为NULL不是标准的一部分。如果这一点得到解决,那么由于指针无效而导致的许多崩溃都不会发生。但是,我已经说过,我可以想到为什么标准会限制这个原因的几个原因:

  
      
  1. 性能:

         

    附加说明可能会降低delete性能。

  2.   
  3. 可能是因为const指针。

         

    然后标准本可以为这个特殊情况做点什么我猜。

  4.   

有没有人知道不允许这个的确切原因?

12 个答案:

答案 0 :(得分:145)

Stroustrup himself回答。摘录:

  

C ++明确允许   执行delete to zero out   一个左值操作数,我曾希望   那些实现会这样做,   但这个想法似乎没有   受到实施者的欢迎。

但他提出的主要问题是删除的论点不一定是左值。

答案 1 :(得分:59)

首先,设置为null将需要一个内存存储变量。确实,您通常在变量中有一个指针,但有时您可能希望删除一个刚刚计算出的地址的对象。 “无效”删除是不可能的。

然后是表演。您可能已经编写了代码,使得指针在 delete 完成后立即超出范围。用null填充它只是浪费时间。 C ++是一种“不需要它,然后你不需要为此付费”的语言。

如果您需要安全,那么您可以使用各种各样的智能指针,或者您可以编写自己的智能指针 - 更好更智能。

答案 2 :(得分:36)

您可以有多个指向该内存的指针。如果为delete指定的指针设置为null,则会产生错误的安全感,但所有其他指针都没有。指针只不过是一个地址,一个数字。它也可能是一个带解除引用操作的int。我的观点是你还必须扫描每一个指针,找到那些引用你刚删除的同一个内存的指针,并将它们归零。扫描该地址的所有指针并将其清空是计算密集的,因为该语言不是为此而设计的。 (尽管其他一些语言构建了他们的引用,以不同的方式实现了类似的目标。)

答案 3 :(得分:18)

指针可以保存在多个变量中,将其中一个设置为NULL仍会在其他变量中留下无效指针。所以你并没有真正获得太多收益,你更有可能造成虚假的安全感。

除此之外,你可以创建自己的功能,做你想做的事情:

template<typename T>
void deleten(T *&ptr) {
  delete ptr;
  ptr = NULL;
}

答案 4 :(得分:12)

因为实际上没有任何需要,并且因为它需要删除指针到指针而不仅仅是指针。

答案 5 :(得分:7)

delete主要用于析构函数,在这种情况下将成员设置为NULL是没有意义的。几行后,在结束},成员不再存在。在赋值运算符中,删除通常后跟一个赋值。

此外,它会使以下代码非法:

T* const foo = new T;
delete foo;

答案 6 :(得分:5)

如果你有一个指针数组,并且你的第二个动作是删除空数组,那么在即将释放内存时,没有必要将每个值设置为null。如果你想要它为null ..给它写null:)

答案 7 :(得分:5)

这是另一个原因;假设delete将其参数设置为NULL:

int *foo = new int;
int *bar = foo;
delete foo;

bar应该设置为NULL吗?你能概括一下吗?

答案 8 :(得分:4)

C ++允许您定义自己的operator new和delete,以便他们可以使用您自己的池分配器。如果你这样做,那么就可以使用new和delete,这些东西不是严格地址,而是说池数组中的索引。在此上下文中,NULL(0)的值可能具有合法含义(指池中的第一项) 因此,删除会自动将NULL设置为其参数并不总是具有以下含义 - 将值设置为无效值。无效值可能不总是NULL。

答案 9 :(得分:4)

C ++的哲学是“只有你使用它才能付出代价”。我想它可以回答你的问题。

有时您可以拥有自己的堆来恢复已删除的内存..或者有时候指针不归任何变量所有。或者指针存储在少数变量中 - 它可能只是其中一个 如您所见,它有许多问题和可能存在的问题。

答案 10 :(得分:3)

将指针自动设置为NULL并不能解决大多数指针使用不良的问题。它会避免的唯一崩溃是你试图删除它两次。如果你在这样的指针上调用成员函数怎么办?它仍会崩溃(假设它访问成员变量)。 C ++不会限制你在NULL指针上调用任何函数,也不应该从性能的角度来看它。

答案 11 :(得分:-1)

我看到人们对这个问题给出了奇怪的答案。

ptr = NULL; 这样一个简单的陈述如何导致性能延迟?

另一个答案是说我们可以有多个指向相同的指针 记忆位置。我们当然可以。在这种情况下,对一个指针的删除操作只会使该指针为NULL(如果删除使指针为NULL),另一个指针将为非NULL并指向可用的内存位置。

解决方案应该是用户应该删除指向同一位置的所有指针。在内部,它应该检查内存是否已经释放,而不是免费。只使指针为NULL。

Stroustrup本可以设计删除以这种方式工作。他认为程序员会照顾这个。所以他忽略了。