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

如何控制、优化或释放联合体(UNION)中未使用的内存?

关于联合体内存优化的解惑

嘿,这个问题戳中了很多刚接触联合体的开发者的误区,先给你理清楚核心逻辑,再聊聊可行的替代方案:

首先纠正一个小误解:你的例子里内存不是64字节哦

你提到long类型分配64字节,这应该是笔误——一般64位系统里unsigned long是8字节(64位),所以你的代码运行后sizeof(my_union)会输出8,而不是64。这个细节先澄清,避免后续理解偏差。

为什么联合体的“剩余内存”没法被“释放”或优化?

联合体的核心设计就是内存共享:它只会分配一块能容纳最大成员的内存空间,所有成员都共用这同一块内存。比如你的例子里:

  • 当你给my_union.C(2字节的unsigned short)赋值时,这2字节是占用了unsigned long那块8字节内存的前2位(具体字节顺序取决于端序),剩下的6字节并不是“未使用的额外内存”——它们本来就是A和B成员的内存区域,只是你当前没用到而已。

换个角度说:联合体不存在“浪费的内存”,它的大小是为了保证所有成员都能正常存储而必须的最小值。你不能只分配小成员的内存,因为那样当你需要存储大成员时就会溢出。

如果真的需要更小的内存占用,该怎么办?

如果你确实希望程序在存储小类型数据时占用更少内存,联合体可能不是最适合的工具,这里有两个常见方案:

1. 直接使用对应类型的变量

如果你确定程序只会用到某一个小类型(比如你的例子里只用到unsigned short),那完全没必要用联合体,直接定义:

unsigned short C = 0x09;
printf("Size: %zu\n", sizeof(C)); // 输出2,完美符合你的需求

这是最简单直接的方式,没有任何内存冗余。

2. 使用标记联合(Tagged Union)+ 动态分配

如果你的场景是需要在不同时刻存储不同类型的数据,同时想根据当前存储的类型动态调整内存占用,可以手动实现一个标记联合:用一个枚举标记当前存储的类型,再配合动态内存分配来只申请需要的空间。示例代码:

#include<stdio.h>
#include<stdlib.h>

// 标记当前存储的数据类型
typedef enum {
    TAG_LONG,
    TAG_INT,
    TAG_SHORT,
    TAG_CHAR
} DataTag;

// 带标记的动态数据结构
typedef struct {
    DataTag tag;
    void* value; // 指向动态分配的内存
} TaggedData;

int main() {
    TaggedData my_data;
    // 存储unsigned short类型的数据
    my_data.tag = TAG_SHORT;
    my_data.value = malloc(sizeof(unsigned short));
    if (!my_data.value) {
        perror("malloc failed");
        return 1;
    }
    *(unsigned short*)my_data.value = 0x09;

    // 查看内存占用:结构体本身的大小(一般是指针+枚举,64位系统是16字节)加上分配的2字节
    printf("TaggedData struct size: %zu\n", sizeof(my_data));
    printf("Allocated value size: %zu\n", sizeof(unsigned short));

    // 使用完记得释放内存
    free(my_data.value);
    return 0;
}

这种方式的好处是,你可以根据当前需要存储的类型,只申请对应大小的内存,避免了固定占用最大成员的内存。但代价是需要手动管理内存(记得free),代码复杂度也会高一点。

总结

  • 联合体的内存共享机制决定了它的大小必须是最大成员的大小,不存在“可优化的剩余内存”——那些空间是为了兼容大成员而预留的共享区域。
  • 如果不需要兼容多种类型,直接用对应大小的变量即可。
  • 如果需要动态切换类型且控制内存占用,标记联合+动态分配是更合适的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:15:37