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

同一段C代码gcc编译运行段错误、clang执行正常的原因是什么

问题原因分析

首先贴出对应的问题代码:

#include <stdio.h> 

int main(int argc, char *argv[]){

    int a;
    int *b = &a;
    a = 10;

    printf("%d %d\n", a, *b);

    int p = 20;
    int *q;
    *q = p;

    printf("%d %d\n", p, *q);

    int *t = NULL;

    return 0;
}

核心根因:代码存在未定义行为

上述代码中int *q;声明后没有做初始化,就直接执行*q = p;解引用赋值操作,q属于野指针,指向的内存地址完全随机,这类操作在C标准中被归类为未定义行为(Undefined Behavior, UB),标准没有对这类操作的运行结果做任何约束,不同编译器、甚至同一编译器的不同版本/不同编译参数的处理结果都可能存在差异。

两款编译器表现差异的具体原因

  • gcc 9.3.0默认编译生成的程序中,未初始化的q刚好指向了操作系统标记为不可写的受保护内存地址,执行写入操作时会触发内存访问异常,操作系统直接抛出段错误终止程序。
  • clang 10.0.0的默认栈内存分配、编译优化逻辑和gcc不同,未初始化的q刚好指向了当前进程地址空间内一块可写的空闲内存,写入操作没有触发系统的内存保护机制,所以看起来可以正常运行。但这只是随机巧合,代码本身的错误依旧存在,更换运行环境、修改代码其他部分都可能随时触发崩溃。

注意:绝对不要依赖未定义行为的偶然表现编写代码,野指针问题必须通过初始化指针到合法可写的内存地址来修复,比如给q分配堆内存、或者让q指向一个已定义的整型变量地址。

内容的提问来源于stack exchange,提问作者Lalitha Prasad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 14:42:04