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

C语言union返回后内部struct成员值不符合预期问题排查

错误核心原因

你的代码问题和结构体定义在union内部/外部没有任何关系,本质是对C语言**union(共用体)**的内存规则理解错误:

  • union的所有成员共享同一块内存空间,内存总大小等于占用空间最大的成员的大小
  • 对任意一个union成员赋值,都会覆盖共享内存中对应位置的原有数据,同一时间只有最后一次被赋值的成员的值是可靠的

结合你的代码具体分析:

  1. 你定义的ku_type共用体中,sd结构体包含2个int类型成员(常规环境下每个int占4字节,整个sd占8字节),id是int类型占4字节。两个成员的内存起始地址完全重合,id占用的内存位置,刚好就是sd结构体第一个成员sd.x所在的前4字节。
  2. 在kuReturner函数中你的赋值顺序是:
    • 先给ku.sd.x赋值11,此时前4字节存11
    • 再给ku.sd.y赋值22,此时后4字节存22
    • 最后给ku.id赋值99,这一步直接把前4字节原来存的11覆盖成了99
  3. 你最后读取ku.sd.x的时候,读的就是前4字节被覆盖后的值99,这完全符合C语言的标准行为,不是编译器或者代码逻辑的其他问题。
修正方法

如果你需要同时保存sd.x、sd.y、id三个独立的值,不要使用union,改用struct(结构体)定义类型即可——结构体的每个成员占用独立的内存空间,赋值不会互相覆盖。参考修正后的代码:

#include <stdio.h>

// 把union替换成struct,成员内存独立
typedef struct ku {
    struct {
        int x;
        int y;
    } sd;
    int id;
} ku_type;

ku_type kuReturner() {
    ku_type ku;
    ku.sd.x = 11;
    ku.sd.y = 22;
    ku.id = 99;
    return ku;
}

int main()
{
    ku_type ku;
    ku = kuReturner();
    // 此处打印会得到预期值11
    printf("%d", ku.sd.x);
    return 0;
}

补充:如果你确实要利用union的内存复用特性,必须遵守“写哪个成员,之后就读哪个成员”的规则,跨成员读取共享内存的值不属于C标准保障的可预期行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:42:13