删除动态分配的变量设置指针为 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 NULL
。 nullptr
关键字引入了类型安全,因为它的作用类似于指针类型,应该优先于类 C 的 NULL
。在 C++11 之前 NULL
被定义为整数 0,因为 C++11 它是 nullptr
.
的别名
要定义您自己的 nullptr
以将其用于 C++11 之前的编译器,请看这里:
关于 delete
或 delete[]
的一个有趣事实是,在 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
指针会立即崩溃。
因为 c++11 你应该使用 nullptr
因为它被定义为指针类型而 NULL
更 int
类型并提高了类型安全性 + 解决了不明确的情况。
在双重删除指针的情况下,在 nullptr
上使用 delete 是安全的并且没有任何反应,但是如果删除已经删除的非空指针,它将导致 undefined behavior 并且程序很可能会崩溃。
在c++ 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" 的值,即 NULL
、0
或指针类型 nullptr
,否则您无法知道您的指针是否指向无效地址。换句话说,当你 delete[]
你的数组你的指针 "doesn't know" 它指向一个不再可用的内存地址。
我无法理解这段代码的结尾(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 NULL
。 nullptr
关键字引入了类型安全,因为它的作用类似于指针类型,应该优先于类 C 的 NULL
。在 C++11 之前 NULL
被定义为整数 0,因为 C++11 它是 nullptr
.
的别名
要定义您自己的 nullptr
以将其用于 C++11 之前的编译器,请看这里:
关于 delete
或 delete[]
的一个有趣事实是,在 nullptr
上使用它是安全的。它写在 cppreference.com or at this SO answer.
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 ofoperator new[](size_t)
or operatornew[](size_t, std::nothrow_t)
.
我们正在将指针设置为 NULL
(0) 以避免悬空指针(指针仍指向不再属于您的同一内存)。在局部变量的情况下,如果函数在删除后没有继续(因此它的明显指针不会被重用),它就没有那么有用了。如果 global/member poitners 是避免错误的良好做法。
访问已经删除的指针可能会导致overwriting/reading随机内存(这可能比崩溃更危险)并导致undefined behavior,而访问NULL
指针会立即崩溃。
因为 c++11 你应该使用 nullptr
因为它被定义为指针类型而 NULL
更 int
类型并提高了类型安全性 + 解决了不明确的情况。
在双重删除指针的情况下,在 nullptr
上使用 delete 是安全的并且没有任何反应,但是如果删除已经删除的非空指针,它将导致 undefined behavior 并且程序很可能会崩溃。
在c++ 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" 的值,即 NULL
、0
或指针类型 nullptr
,否则您无法知道您的指针是否指向无效地址。换句话说,当你 delete[]
你的数组你的指针 "doesn't know" 它指向一个不再可用的内存地址。