Is the pointer guaranteed to preserve its value after `delete` in C++?

折月煮酒 提交于 2019-11-26 11:23:07

问题


Inspired by this question.

Suppose in C++ code I have a valid pointer and properly delete it. According to C++ standard, the pointer will become invalid (3.7.3.2/4 - the deallocation function will render invalid all pointers referring to all parts of deallocated storage).

At least in most implementations it preserves the value and will store exactly the same address as before delete, however using the value is undefined behavior.

Does the standard guarantee that the pointer will preserve its value or is the value allowed to change?


回答1:


No, it's not guaranteed and an implementation may legitimately assign zero to an lvalue operand to delete.

Bjarne Stroustrup had hoped that implementations would choose to do this, but not many do.

http://www.stroustrup.com/bs_faq2.html#delete-zero




回答2:


If, for whatever reason, you want to be sure the pointer variable is not changed by delete, write:

delete p + 0;



回答3:


I believe that most implementations will keep the value, only for the sake of having no reason to change it. But regardless of whether the value is kept, it's still a useless pointer, is it not?




回答4:


The signature of the global operator delete, as required by the standard 3.7.3.2/2:

Each deallocation function shall return void and its first parameter shall be void*.

This means that delete cannot modify the pointer you pass to it, and it will always retain its value.




回答5:


Consider, how would you check or rely on any "yes" or "no" answer? You can't. Or, you can, but the result of that checking (except for nullpointer) is Undefined Behavior.

You can't check a non-null value after a delete, so the question is in general meaningless.

Also, the argument to delete can be an rvalue expression, so the question is meaningless.

Cheers & hth.,




回答6:


A pointer is not guaranteed to be of any meaningful value in of itself other than the range in which it was allocated and one past the end of that range.

What you might be questioning is whether, say, you were doing your own leak checking so you wrote function to remove a pointer from a map after you had done a delete. That would use std::less which is guaranteed to work with pointers that do not point within a range, and would presumably work too with pointers that pointed to memory that is no longer valid.

Of course you might get your garbage collecting to do the "remove" just before deleting the memory it was pointing to.

As it is with the standard, if the value you pass to delete is not an l-value it is guaranteed to maintain the same value, but if it is an l-value it is implementation defined.




回答7:


This question is important! I have seen that Visual Studio 2017 has changed pointer value after "delete". It coused a problem because I has using memory tracing tool. The tool was collecting pointers after each operator "new" and was checking them after "delete". Pseudo code:

Data* New(const size_t count)
{
    Data* const ptr(new Data[count]);
    #ifdef TEST_MODE
    DebugMemory.Collect(ptr);
    #endif
    return ptr;
}

void Delete(Data* const ptr)
{
    delete[] ptr;
    #ifdef TEST_MODE
    DebugMemory.Test(ptr);
    #endif
}

This code works good on Visual Studio 2008 but was failing on Visual Studio 2017 so I have changed the order of operations in second function.

However The question is good and the problem exists. Experienced engineers should be aware of that.



来源:https://stackoverflow.com/questions/5002055/is-the-pointer-guaranteed-to-preserve-its-value-after-delete-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!