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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/704466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:50:50  来源:igfitidea点击:

Why doesn't delete set the pointer to NULL?

c++memory-managementdelete-operator

提问by aJ.

I always wondered why automatic setting of the pointer to NULL after deleteis not part of the standard. If this gets taken care of then many of the crashes due to an invalid pointer would not occur. But having said that I can think of couple of reasons why the standard would have restricted this:

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

  1. Performance:

    An additional instruction could slow down the deleteperformance.

  2. Could it be because of constpointers.

    Then again standard could have done something for this special case I guess.

  1. 表现:

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

  2. 可能是因为const指针。

    然后,我猜标准本可以为这种特殊情况做一些事情。

Does anyone know exact reasons for not allowing this?

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

回答by Dan Olson

Stroustrup himselfanswers. An excerpt:

Stroustrup 自己回答。摘录:

C++ explicitly allows an implementation of delete to zero out an lvalue operand, and I had hoped that implementations would do that, but that idea doesn't seem to have become popular with implementers.

C++ 明确允许 delete 的实现将左值操作数归零,我曾希望实现会这样做,但这个想法似乎并没有在实现者中流行起来。

But the main issue he raises is that delete's argument need not be an lvalue.

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

回答by sharptooth

First, setting to null would require a memory stored variable. It's true, that you usually have a pointer in a variable but sometimes you might want to deletean object at a just calculated address. That would be impossible with "nullifying" delete.

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

Then comes performance. You might have written code in such a way that the pointer will go out of scope immediately after deleteis done. Filling it with null is just a waste of time. And C++ is a language with "don't need it? then you don't have to pay for it" ideology.

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

If you need safety there's a wide range of smart pointers at you service or you can write your own - better and smarter.

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

回答by AaronLS

You can have multiple pointers pointing to that memory. It would create a false sense of security if the pointer you specified for the delete got set to null, but all the other pointers did not. A pointer is nothing more than an address, a number. It might as well be an int with a dereference operation. My point is you would have to also scan every single pointer to find those that are referencing the same memory you just deleted, and null them out as well. It would be computationally intense to scan all the pointers for that address and null them out, because the language is not designed for that. (Although some other languages structure their references to accomplish a similar goal in a different way.)

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

回答by sth

A pointer can be saved in more than one variable, setting one of these to NULL would still leave invalid pointers in the other variables. So you don't really gain much, you are more likely creating a false sense of security.

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

Besides of that, you can create your own function that does what you want:

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

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

回答by snemarch

Because there isn't really any need to, and because it would require delete taking pointer-to-pointer rather than just pointer.

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

回答by MSalters

deleteis used mostly in destructors, in which case setting a member to NULL is pointless. A few lines later, at the closing }, the member no longer exists. In assignment operators, a delete is typically followed by an assignment anyway.

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

Also, it would render the following code illegal:

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

T* const foo = new T;
delete foo;

回答by SingleNegationElimination

Here's another reason; suppose delete does set its argument to NULL:

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

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

Should bar get set to NULL? Can you generalize this?

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

回答by Dead account

If you have an array of pointers, and your second action is to delete the empty array, then there is no point setting each value to null when the memory is about to be freed. If you want it to be null.. write null to it :)

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

回答by bayda

Philosophy of C++ is "pay for it only if you use it". I think it may answer your question.

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

Also sometimes you could have your own heap which will recover deleted memory.. or sometimes pointer not owned by any variable. Or pointer stored in few variables - it possible zero just one of them.
As you can see it have many issues and possible problems.

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

回答by shoosh

C++ allows you to define your own operator new and delete so that for instance they would use your own pool allocator. If you do this then it is possible to use new and delete with things that are not strictly addresses but say indexes in your pool array. In this context the value of NULL (0) might have a legal meaning (referring to the first item in the pool).
So having delete set NULL automatically to its argument doesn't always have the meaning of - set the value to an invalid value. The invalid value may not always be NULL.

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