C语言超出指定数组大小访问:声明20长度数组可写至索引23才报错原因
该现象的具体成因
- 首先你的代码存在明确的数组越界访问问题:你定义的
int marks[20]合法下标范围是0~19,而你循环控制条件是i <= 23,相当于访问了数组外的4个int空间,这属于C语言标准定义的未定义行为,运行结果没有确定性。 - 越界后没有立刻报错、直到写入第24个元素才触发报错,是现代编译器默认开启的**栈溢出保护(金丝雀机制)**的运行逻辑导致的:
编译器会在栈上的数组缓冲区和栈帧返回地址之间插入一个随机生成的特殊值(俗称金丝雀值),函数执行结束前会校验这个值是否和初始值一致,只有当值被篡改时才会抛出stack smashing detected报错。 - 你当前的栈布局里,
marks数组之后的栈空间先分配了其他无关内容(比如你定义的变量i的存储位置、栈上的对齐填充空间等),你从i=20开始越界写入时,先覆盖的是这些不受保护的空间,直到i=23时写入的内容刚好覆盖到了金丝雀值的存储位置,函数退出校验时检测到值被篡改,才触发了崩溃报错。
对应问题代码:
int marks[20], i; for (i = 0; i <= 23; i++) { printf("enter la note de letudiant ! \n"); scanf("%d", &marks[i]); } for (i = 0; i <= 23; i++) { printf("%d\n", marks[i]); }
内容的提问来源于stack exchange,提问作者abdo
相关产品推荐
相关产品推荐

