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

修改C语言main函数for循环的argc为固定值后程序崩溃原因解析

超出argc范围访问argv为何会读取到环境变量甚至崩溃?

最小可复现代码

#include <stdio.h>

int main( int argc, char* argv[])
{
    printf (" this is the contents of argc:%d\n",argc);
            
    int i;

    for (i = 0; i < argc ; i++){
       printf(" argv = %d = %s\n",i,argv[i]);
    }
      
    return 0;
}

异常现象

当把for循环中的argc改为固定数值(比如10)时,运行程序会输出超出命令行参数的内容:

$ ./argc one two three
 this is the contents of argc:4
 argv = 0 = ./argc
 argv = 1 = one
 argv = 2 = two
 argv = 3 = three
 argv = 4 = (null)
 argv = 5 = SHELL=/bin/bash
 argv = 6 = SESSION_MANAGER=local/wajih:@/tmp/.ICE-unix/1230,unix/wajih:/tmp/.ICE-unix/1230
 argv = 7 = QT_ACCESSIBILITY=1
 argv = 8 = COLORTERM=truecolor
 argv = 9 = XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg

如果将上限改为100,输出会包含大量环境变量,最终触发崩溃:

argv = 54 = GDMSESSION=ubuntu
 argv = 55 = DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
 argv = 56 = LC_NUMERIC=ar_AE.UTF-8
 argv = 57 = _=./argc
 argv = 58 = OLDPWD=/home/wajih
 argv = 59 = (null)
Segmentation fault (core dumped).

原因解析

  • 内存布局特性:在Linux等系统的进程内存中,argv数组的末尾直接挨着环境变量列表(由全局变量environ指向)。C标准规定argv[argc]必须是NULL,而环境变量列表同样以NULL结尾。当循环上限超过argc时,就会越界访问到argv之后的环境变量区域,这就是你看到各种系统环境变量的原因。
  • 段错误的本质:环境变量列表也有边界,当继续越界到环境变量之后的内存区域时,这些内存要么是未分配的垃圾数据,要么是进程没有访问权限的内存。此时操作系统会触发段错误,终止进程以保护内存安全。
  • 未定义行为:C标准仅保证argv[0]到argv[argc-1]是有效的命令行参数,argv[argc]为NULL。超出这个范围的访问属于未定义行为,结果完全不可控——读取环境变量、垃圾数据、直接崩溃都是可能的表现。

内容的提问来源于stack exchange,提问作者Wajih Mansouri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 15:27:33