为什么 C/C++ 会在数组索引越界的情况下进行区分
#include <stdio.h>
int main()
{
int a[10];
a[3]=4;
a[11]=3;//does not give segmentation fault
a[25]=4;//does not give segmentation fault
a[20000]=3; //gives segmentation fault
return 0;
}
我了解它正在尝试访问分配给进程或线程的内存,以防 a[11]
或 a[25]
超出堆栈范围a[20000]
的情况。
为什么编译器或链接器不给出错误,他们不知道数组大小吗?如果不是,那么 sizeof(a)
如何正常工作?
最佳答案
问题在于 C/C++ 实际上并没有对数组进行任何边界检查。这取决于操作系统来确保您访问的是有效内存。
在这种特殊情况下,您要声明一个基于堆栈的数组。根据特定的实现,在数组边界之外访问将只访问已分配堆栈空间的另一部分(大多数操作系统和线程为堆栈保留一定部分的内存)。只要你碰巧在预先分配的堆栈空间中玩耍,一切都不会崩溃(注意我没有说工作)。
最后一行发生的情况是,您现在访问的内存超出了为堆栈分配的内存部分。因此,您正在索引未分配给您的进程或以只读方式分配的内存部分。操作系统看到这一点并向进程发送段错误。
这是 C/C++ 在边界检查方面如此危险的原因之一。
关于c++ - 数组索引越界行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/671703/