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

为何通过非const指针修改const static变量会触发段错误?

问题分析:修改const变量的未定义行为与存储位置差异

先贴出你的代码:

#include <stdio.h>

int main() {
    // case 1
    const int a = 10;
    int * ptr1 = &a;
    *ptr1 = 11;
    printf("%d\n",*ptr1);
    
    // case 2
    const static int b = 10;
    static int * ptr2 = &b;
    *ptr2 = 11;
    printf("%d\n",*ptr2);
    return 0;
}

核心前提:修改const变量是未定义行为

首先要明确:C标准规定,通过非const指针修改const限定的变量属于未定义行为——编译器可自由选择处理方式,可能正常运行、崩溃或出现诡异结果,case1能运行只是编译器未触发错误,绝不代表操作合法。

两个case的差异根源:变量存储位置不同

Case1:局部const变量(无static)

局部变量(包括const修饰的)默认存在栈区,栈区是可读写的内存区域。你用int* ptr1 = &a隐式丢弃const属性(GCC会给出警告)后,修改栈内存是允许的,所以程序没崩溃,但这依然违反标准,换编译器或优化等级可能出问题。

Case2:const static变量

static修饰的变量(无论是否const)会存在全局/静态存储区,而const修饰的静态变量,GCC通常会把它放到只读数据段(.rodata)。只读数据段是操作系统标记为不可写的内存区域,当你试图通过指针修改这里的内容时,操作系统会触发内存保护机制,抛出段错误(SIGSEGV),阻止非法写入。

补充:编译器优化的影响

对于const局部变量,编译器可能做常量折叠优化——比如直接把引用a的地方替换成字面量10,但你用指针修改的是栈上的实际存储,所以printf能看到修改后的值;而const static变量在只读段,编译器更可能直接将其当作常量处理,同时内存本身不可写,修改时直接崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 20:12:40