Dre*_*rew -1 c++ new-operator dynamic-memory-allocation
为什么C++中的new []操作符实际上创建了一个长度为+ 1的数组?例如,请参阅以下代码:
#include <iostream>
int main()
{
std::cout << "Enter a positive integer: ";
int length;
std::cin >> length;
int *array = new int[length]; // use array new. Note that length does not need to be constant!
//int *array;
std::cout << "I just allocated an array of integers of length " << length << '\n';
for (int n = 0; n<=length+1; n++)
{
array[n] = 1; // set element n to value 1
}
std::cout << "array[0] " << array[0] << '\n';
std::cout << "array[length-1] " << array[length-1] << '\n';
std::cout << "array[length] " << array[length] << '\n';
std::cout << "array[length+1] " << array[length+1] << '\n';
delete[] array; // use array delete to deallocate array
array = 0; // use nullptr instead of 0 in C++11
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我们动态创建一个长度为"length"的数组,但我们能够在索引长度+ 1处分配一个值.如果我们尝试长度+ 2,我们会收到错误.
为什么是这样?为什么C++使长度=长度+ 1?
它没有.您可以计算地址 array + n,以便检查另一个地址是否小于它.尝试访问该元素array[n]是未定义的行为,这意味着该程序变得毫无意义,并且允许编译器执行任何操作.字面意思; 一个老版本的海湾合作委员会,如果它看到一个#pragma指令,在终端上开始了一个roguelike游戏.(谢谢,Revolver_Ocelot,提醒我:这是技术上实现定义的行为,一个不同的类别.)即使计算地址array + n + 1也是未定义的行为.
因为它可以做任何事情,你试过的特定编译器决定让你自己射击.例如,如果数组之后的下两个单词是堆中另一个块的标头,则可能会出现内存损坏错误.或者,编译器可能将数组存储在内存空间的顶部,地址为&array[n+1] is aNULL`指针,并尝试取消引用它会导致分段错误.或者下一页内存不可读或写,尝试访问它会导致程序出现保护错误.或者实现边界 - 在运行时检查您的数组访问并使程序崩溃.也许运行时在数组之后粘贴了一个canary值,然后检查它是否被覆盖.或许它偶然发生在工作中.
在实践中,您真的希望编译器为您捕获这些错误,而不是试图追踪缓冲区溢出导致的错误.使用std::vector动态数组比动态数组更好.如果必须使用数组,则需要自己检查所有访问是否都在入站,因为您不能依赖编译器为您执行此操作并跳过它们是导致错误的主要原因.
| 归档时间: |
|
| 查看次数: |
283 次 |
| 最近记录: |