You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 11:07:03