删除动态分配的变量设置指针为 0

Deleting dynamically allocated variables setting pointer to 0

我无法理解这段代码的结尾(array = 0;):

#include <iostream>

int main()
{
    std::cout << "Enter a positive integer: ";
    int length;
    std::cin >> length;

    int *array = new int[length];

    std::cout << "I just allocated an array of integers of length " << length << '\n';

    array[0] = 5; // set element 0 to value 5

    delete[] array; // use array delete to deallocate array
    array = 0; // use nullptr instead of 0 in C++11

    return 0;
}

最后删除一个动态分配的数组(返回OS),然后赋值0。

为什么要这样做?数组返回到OS后,就不用赋值0了吧?

代码来自:http://www.learncpp.com/cpp-tutorial/6-9a-dynamically-allocating-arrays/

这样做是为了将指针设置为NULL(无论是在C++中,我们更喜欢nullptr,因为NULL和0可能是不同的东西)。

此策略消除了 悬空指针 的可能性,因为数组可能已被删除,但这并不意味着它已设置为 NULL

如果我们不这样做,我们 运行 检查指针是否为 NULL 的风险(在我们的代码后面),我们将看到它不是 [=10] =], 错误地认为指针可以被访问,导致未定义的行为。

After array has been returned to the OS, there is no need to assign it a value of 0, right?

你说得对,不需要它,因为内存已被 operator delete 释放(解除分配)。但是想想这样一种情况,你可能在你的代码(函数、循环等)的另一个地方使用指针,在你对它使用 delete[] 之后。

array 变量在 delete[] 语句被调用后仍然保存旧分配的地址 (dangling pointer). If you would access that address you would get undefined bahaviour (UB) 因为内存不再是你的,在大多数情况下你的程序会崩溃。

为了避免这种情况,您可以像这样进行 null pointer 检查:

if (array != nullptr)
{
   /* access array */
   ...
}

正在根据地址 0 检查指针,地址 0 表示无效地址。

为了使检查成为可能,如果 C++11 不可用,请将指针设置为 nullptr or NULLnullptr 关键字引入了类型安全,因为它的作用类似于指针类型,应该优先于类 C 的 NULL。在 C++11 之前 NULL 被定义为整数 0,因为 C++11 它是 nullptr.
的别名 要定义您自己的 nullptr 以将其用于 C++11 之前的编译器,请看这里:


关于 deletedelete[] 的一个有趣事实是,在 nullptr 上使用它是安全的。它写在 cppreference.com or at this SO answer.

的第 2 点

operator delete, operator delete[]

2) [...] The behavior of the standard library implementation of this function is undefined unless ptr is a null pointer or is a pointer previously obtained from the standard library implementation of operator new[](size_t) or operator new[](size_t, std::nothrow_t).

我们正在将指针设置为 NULL (0) 以避免悬空指针(指针仍指向不再属于您的同一内存)。在局部变量的情况下,如果函数在删除后没有继续(因此它的明显指针不会被重用),它就没有那么有用了。如果 global/member poitners 是避免错误的良好做法。

访问已经删除的指针可能会导致overwriting/reading随机内存(这可能比崩溃更危险)并导致undefined behavior,而访问NULL指针会立即崩溃。

因为 你应该使用 nullptr 因为它被定义为指针类型而 NULLint 类型并提高了类型安全性 + 解决了不明确的情况。

在双重删除指针的情况下,在 nullptr 上使用 delete 是安全的并且没有任何反应,但是如果删除已经删除的非空指针,它将导致 undefined behavior 并且程序很可能会崩溃。

you should avoid using pure pointers since there are STL containers (which frees their resources them self (RAII)) for this usage or smart pointers.

std::vector<int> array{1,2,3,4,5};

您分配给一个通常称为 "invalid address" 的值,即 NULL0 或指针类型 nullptr,否则您无法知道您的指针是否指向无效地址。换句话说,当你 delete[] 你的数组你的指针 "doesn't know" 它指向一个不再可用的内存地址。