指针是否保证在C ++中的`delete`后保留其值?

时间:2011-02-15 09:49:34

标签: c++ pointers delete-operator

this question的启发。

假设在C ++代码中我有一个有效的指针并正确地delete它。根据C ++标准,指针将变为无效(3.7.3.2/4 - 解除分配函数将使所有指针无效,指向释放存储的所有部分)。

至少在大多数实现中,它会保留该值并存储与delete之前完全相同的地址,但是using the value is undefined behavior

标准是否保证指针将保留其值或允许更改的值?

7 个答案:

答案 0 :(得分:19)

不,它不能得到保证,并且实现可以合理地将左值操作数归零给delete

Bjarne Stroustrup曾希望实施会选择这样做,但并不是很多。

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

答案 1 :(得分:10)

如果出于某种原因,您希望确保指针变量未被delete更改,请写:

delete p + 0;

答案 2 :(得分:3)

我相信大多数实现都会保留这个值,只是为了没有理由改变它。但无论值是否保留,它仍然是一个无用的指针,不是吗?

答案 3 :(得分:2)

全局运算符delete的签名,符合标准3.7.3.2/2:

的要求

每个释放函数都应返回void,其第一个参数应为void *。

这意味着删除不能修改传递给它的指针,它将始终保留其值。

答案 4 :(得分:1)

除了分配指针的范围和超出该范围结束的指针之外,指针不能保证具有任何有意义的值。

您可能会质疑的是,您是否正在进行自己的泄漏检查,因此您在完成删除后编写了从地图中删除指针的功能。这将使用std :: less,它可以保证与指向范围内的指针一起工作,并且可能也会使用指向不再有效的内存的指针。

当然,在删除它指向的内存之前,您可能会收集垃圾进行“删除”。

与标准一样,如果传递给delete的值不是l值,则保证保持相同的值,但如果它是l值,则它是实现定义的。

答案 5 :(得分:1)

考虑一下,您如何检查或依赖任何“是”或“否”答案?你不能。或者,您可以,但检查的结果(nullpointer除外)是Undefined Behavior。

您无法在delete之后检查非空值,因此问题通常是无意义

此外,delete的参数可以是右值表达式,因此问题毫无意义。

干杯&第h。,

答案 6 :(得分:1)

这个问题很重要! 我已经看到Visual Studio 2017在“删除”之后更改了指针值。它引起了一个问题,因为我使用了内存跟踪工具。该工具在每个操作员“新建”之后收集指针,并在“删除”之后检查它们。伪代码:

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
}

此代码在Visual Studio 2008上运行良好,但在Visual Studio 2017上失败,因此我更改了第二个功能的操作顺序。

但是,问题很好,并且存在问题。经验丰富的工程师应该意识到这一点。