我在完整的参考书中阅读了这一段
C没有对数组进行边界检查。你可以覆盖任何一端 一个数组并写入其他变量的数据,甚至写入 程序的代码。作为程序员,提供边界是你的工作 检查需要的地方。例如,此代码将在不编译的情况下编译 错误,但它是不正确的,因为for循环将导致数组 算是超支。
#include <stdio.h> int main(){ int count[10], i; /* this causes count to be overrun */ for(i=0; i<15; i++) count[i] = i; for(i=0; i<15; i++) printf("%d ",count[i]); return 0; }
当我尝试代码时,它给了我
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
然后屏幕上显示运行时错误。错误是
array.exe已停止工作
我的问题是:该错误的类型是什么?这是否意味着我的IDE会检查数组的界限?
答案 0 :(得分:3)
第一个循环到达i=10
的那一刻,你进入undefined behaviour的领域(因为你写的是count
的结尾)。从那时起,任何事情都可能发生。
答案 1 :(得分:3)
C不检查数组idexing,它只做简单的指针算术。也就是说,标准将操作array[i]
定义为array + i
根据计算结果的内存地址,可能会发生很多事情:
地址指向函数的局部变量的位置:您修改局部变量。例如:
int main()
{
int array[10];
int a = 0;
array[11] = 22;
printf(a%i,a); /* Prints 22 */
}
请记住,这里的重点是缓冲区溢出具有未定义的行为。我的示例无法工作,因为编译器可以在编译期间自由地重新排序变量布局,用于内存对齐和优化目的。
地址指向全局变量的位置(这是一个非常大的索引/跳转,但可以发生):效果与局部变量情况相同。< / p>
地址指向子例程存储返回地址的位置:许多架构将函数的返回地址存储在寄存器中,但如果架构将其存储在堆栈帧中功能......哇。尝试调试!!! :)
地址超出了进程的内存空间:现代操作系统总是检查内存访问以防止这种情况发生,所以当发生这种情况时,操作系统会把你踢进屁股并抛出一个例外。
最后请注意,事情仅适用于发布编译。在调试模式下,编译器添加了大量代码来检查这类事件(提供)一个易于理解且易于调试的异常。
例如:在分配动态数组时,windows debug-heap首先填充将与标志一起使用的内存空间,该标志表示内存空间已准备好使用,但它不包含任何数据:那就是hexspeak < EM> 0xBADF00D 。在此之后,malloc
检索内存位置,在数组周围添加hexspeak以提供边界检查。
有关完整说明,请参阅this article。
答案 2 :(得分:1)
你的IDE与它无关。操作系统杀死了你的程序,因为它试图访问不属于它的内存。
此类错误通常称为访问冲突。
答案 3 :(得分:0)
那很好 - 你读过这篇文章的重点......
你应该做的是限制for循环,使它只从0到9运行。
或者,如果你真的需要15个项目,请展开数组以获取它们......