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

为何修改C语言只读结构体成员时,两段代码表现不同?

全局与局部const结构体修改行为差异的原因

两段代码的核心区别在于const修饰的结构体变量B的存储位置不同,直接导致了修改操作的不同结果:

第一段代码(全局const结构体)

全局作用域的const变量会被编译器分配到只读数据段(.rodata),这个内存区域被操作系统标记为只读属性。当你用指针int *ptr = &B.a;强制转换并尝试修改*ptr时,本质是对只读内存执行写操作,会触发内存访问错误(比如Linux下的段错误Segmentation fault),因此修改无法成功。

对应的代码:

typedef struct {
    int a;
    int b;
}A;
const A B={
    .a = 5,
    .b = 1,
};
int main()
{
    int *ptr = &B.a;
    *ptr = 12;
  
    printf("var = %d\n", B.a);
    return 0;
}

第二段代码(局部const结构体)

定义在main函数内的局部const变量会被分配到栈内存,栈内存本身是可读写的。这里的const只是编译器提供的语法约束——编译时会检查你是否直接修改B.a,但不会给栈上的这个变量设置内存级别的只读属性。当你通过指针强制转换绕过编译检查后,写操作可以直接修改栈内存里的内容,因此printf能输出修改后的值。

对应的代码:

typedef struct {
    int a;
    int b;
}A;

int main()
{
    const A B={
        .a = 5,
        .b = 1,
    };
    int *ptr = &B.a;
    *ptr = 12;
  
    printf("var = %d\n", B.a);
    return 0;
}

需要注意:这种通过指针强制修改const变量的行为属于C语言未定义行为,标准不保证任何运行结果,不同编译器、操作系统甚至编译优化选项都可能让结果不一样,实际开发中绝对不能这么写。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 17:11:14