MinGW环境下C语言越界指针为何停止?输出值含义是什么?
关于C语言指针越界访问的问题
测试用C代码
#include <stdio.h> void ar1(int *a); int main() { int a[][3]={{100,200,300},{500,900,800},{9,88,45}}; ar1(a[0]); } void ar1(int *a) { while(1) {++*a; printf("%10d",*a); ++a; printf(" || %10d \n",a); } }
程序运行输出
101 || 6422272 201 || 6422276 301 || 6422280 501 || 6422284 901 || 6422288 801 || 6422292 10 || 6422296 89 || 6422300 46 || 6422304 4194433 || 6422308 6422289 || 6422312 6422357 || 6422316 4199049 || 6422320 2 || 6422324 12591553 || 6422328 12588985 || 6422332 -2 || 6422336 3 || 6422340 1 || 6422344 6422357 || 6422348 2001176782 || 6422352 4034561 || 6422356 6422405 || 6422360 4199158 || 6422364 2 || 6422368 1 || 6422372 1 || 6422376 1 || 6422380 1 || 6422384 1 || 6422388 1 || 6422392 2004908970 || 6422396 4034561 || 6422400 2004908945 || 6422404 6422493 || 6422408 2007416108 || 6422412 4034561 || 6422416 991310042 || 6422420 1 || 6422424 1 || 6422428 4034561 || 6422432 1 || 6422436 1 || 6422440 1 || 6422444 1 || 6422448 1 || 6422452 1 || 6422456 1 || 6422460 1 || 6422464 1 || 6422468 6422417 || 6422472 1 || 6422476 6422501 || 6422480 2007494273 || 6422484 1288080694 || 6422488 1 || 6422492 6422509 || 6422496 2007415984 || 6422500 0 || 6422504 2007601904 || 6422508 1 || 6422512 1 || 6422516 4199137 || 6422520 4034561 || 6422524 1 || 6422528
提问内容
我尝试用指针访问二维数组,随后故意让指针越界访问不应访问的内存,但程序运行到某一位置就停止了。想请教:程序为何会在此处停止?输出的这些数值代表什么?我猜测可能是到达了编译器分配的内存末尾,且这些值并非乱码而是自引用指针,是否正确?
问题解答
1. 程序停止的原因
代码中使用while(1)构建了无限循环,指针持续递增并访问内存,这属于C语言标准中定义的未定义行为,结果完全不可控。程序停止通常有两种核心原因:
- 指针越界后访问到了操作系统禁止用户程序读写的内存区域(比如内核空间、其他进程的私有内存),触发了内存访问错误(段错误/Segmentation Fault),操作系统会直接终止程序进程以保护系统安全。
- 指针可能修改了程序栈帧的关键数据(比如函数返回地址、栈帧基址),导致程序执行流程彻底混乱,最终触发崩溃。
2. 输出数值的含义
- 前9行的数值是你初始化的二维数组元素自增后的值:对应数组中
100→101、200→201……45→46的所有元素,这部分属于合法内存访问的结果。 - 从第10行开始的数值,是指针越界后读取到的内存中原本存在的垃圾数据:可能是栈上的其他局部变量、函数调用的返回地址、栈帧的维护信息、全局变量的残留值,甚至是内存中的随机内容。你看到的类似
6422289这类值,本质是把指针(内存地址)用%10d格式符强制转换为int类型输出的结果——在64位系统下,指针是8字节,int是4字节,这里会截断地址的高位,所以输出的并不是完整的地址,更不是什么自引用指针。
3. 关于你的猜测的纠正
- 「到达编译器分配的内存末尾」的说法不准确:编译器仅为你的数组分配了栈内存,但栈内存之外还有堆、全局区、内核区等内存区域,程序崩溃是因为访问了操作系统保护的内存,而非单纯的编译器分配内存的边界。
- 「这些值是自引用指针」的猜测也不成立:这些值要么是栈上的残留数据,要么是被截断的内存地址,不存在所谓的自引用逻辑,只是未定义行为下的随机输出。
内容的提问来源于stack exchange,提问作者Ha'Penny
相关产品推荐
相关产品推荐

