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

时间:2017-08-28 08:09:55

标签: c++ arrays pointers memory-management dynamic-allocation

我无法理解此代码的结尾(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/

4 个答案:

答案 0 :(得分:14)

  

将数组返回给操作系统后,无需为其赋值0,对吗?

你是对的,因为内存被operator delete释放(释放),所以不需要它。但是想想在你使用delete[]之后你可以在代码中的另一个地方(函数,循环等)使用指针的情况。

在调用array语句(dangling pointer)后,delete[]变量仍保留旧分配的地址。如果您访问该地址,您将获得undefined bahaviour (UB),因为内存不再是您的,在大多数情况下您的程序会崩溃。

为避免您执行null pointer检查,例如:

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

检查指针对地址0,表示无效地址。

如果C ++ 11不可用,则可以将指针设置为nullptrNULLnullptr关键字引入了类型安全性,因为它的作用类似于指针类型,应优先于类似C的NULL。在预C ++ 11中,NULL被定义为整数0,因为C ++ 11它是nullptr的别名。
要定义自己的nullptr以将其用于预C ++ 11编译器,请在此处查看:How to define our own nullptr in c++98?

有关deletedelete[]的一个有趣的事实是,在nullptr上使用它是安全的。它写在cppreference.com上的第2点或SO answer处。

  

操作员删除,操作员删除[]

     

2)   [...]此函数的标准库实现的行为是未定义的,除非ptr是空指针或者是先前从operator new[](size_t)或运算符{{1}的标准库实现获得的指针}。

答案 1 :(得分:8)

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

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

由于您应该使用nullptr,因为它定义为指针类型,而NULL更多int类型并提高了类型安全性+解决了模棱两可的情况。

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

中,您应该避免使用纯指针,因为有STL容器(可以自行释放资源(RAII))用于此用法或smart pointers

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

答案 2 :(得分:3)

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

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

如果我们不这样做,我们冒着检查指针是否为NULL的风险(我们的代码中的后一个),我们会发现它不是{{1错误地认为指针可以被访问,并导致未定义的行为。

答案 3 :(得分:1)

您指定的值通常称为“无效地址”,即NULL0或指针类型nullptr,因为否则您无法知道您是否指针指向无效的地址。换句话说,当您delete[]数组时,指针“不知道”它指向不再可用的内存地址。