137

我一直想知道为什么删除后将指针自动设置为 NULL不是标准的一部分。如果这得到照顾,那么由于指针无效而导致的许多崩溃都不会发生。但是话虽如此,我可以想到标准会限制这一点的几个原因:

  1. 表现:

    额外的指令可能会降低delete性能。

  2. 可能是因为const指针。

    然后我想标准可以为这种特殊情况做点什么。

有谁知道不允许这样做的确切原因?

4

12 回答 12

159

Stroustrup 自己回答。摘录:

C++ 明确允许删除的实现将左值操作数清零,我曾希望实现能够做到这一点,但这个想法似乎并没有在实现者中流行。

但他提出的主要问题是 delete 的参数不必是左值。

于 2009-04-01T08:23:00.000 回答
68

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

然后是表演。您可能以这样一种方式编写代码,即在删除完成后指针将立即超出范围。用 null 填充它只是浪费时间。而 C++ 是一种具有“不需要它?那么你就不必为此付费”意识形态的语言。

如果您需要安全,可以使用各种智能指针为您服务,或者您可以自己编写——更好、更智能。

于 2009-04-01T07:56:19.907 回答
42

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

于 2009-04-01T07:58:03.693 回答
20

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

除此之外,您可以创建自己的函数来执行您想要的操作:

template<typename T>
void deleten(T *&ptr) {
  delete ptr;
  ptr = NULL;
}
于 2009-04-01T08:00:37.277 回答
12

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

于 2009-04-01T07:50:52.447 回答
8

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

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

T* const foo = new T;
delete foo;
于 2009-04-02T08:25:16.600 回答
6

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

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

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

于 2010-10-01T03:22:16.040 回答
5

如果您有一个指针数组,并且您的第二个操作是删除空数组,那么在即将释放内存时将每个值设置为 null 是没有意义的。如果您希望它为 null .. 将 null 写入它:)

于 2009-04-01T07:52:35.737 回答
4

C++ 允许您定义自己的运算符 new 和 delete,以便它们使用您自己的池分配器。如果您这样做,则可以将 new 和 delete 用于不是严格地址但表示池数组中的索引的东西。在这种情况下,NULL (0) 的值可能具有法律意义(指池中的第一项)。
因此,将 delete 设置为 NULL 自动为其参数设置并不总是具有以下含义 - 将值设置为无效值。无效值可能并不总是 NULL。

于 2009-04-01T08:09:49.640 回答
4

C++ 的哲学是“只有在使用时才付费”。我想它可以回答你的问题。

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

于 2009-04-01T08:26:12.473 回答
3

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

于 2009-04-01T08:18:14.020 回答
-2

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

指针=空;这么简单的语句怎么会导致性能延迟?

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

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

Stroustrup 可以设计删除以这种方式工作。他认为程序员会解决这个问题。所以他忽略了。

于 2016-04-05T05:36:03.887 回答