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

如何为C语言结构体中的共用体数组进行动态内存分配

问题排查

  • 你定义Registers共用体的语法存在错误,union关键字后缺少左大括号,正确的基础定义如下:
typedef union {
    uint16_t reg;
    uint8_t low;
    uint8_t high;
} Registers;
  • malloc内存大小计算逻辑错误,你需要分配的是amount个Registers类型的元素,直接用sizeof(Registers)计算单元素大小即可,不需要手动写2字节,避免后续共用体调整大小后出现内存越界问题。
  • 你的猜测是错误的:Config cfg;仅在栈上分配了结构体本身的内存,结构体里的regs指针此时是野指针,你给它赋值malloc返回的动态内存地址的逻辑是完全成立的,只是之前的大小参数写错了。

正确实现方案

基础动态分配版本

#include <stdint.h>
#include <stdlib.h>

typedef union {
    uint16_t reg;
    uint8_t low;
    uint8_t high;
} Registers;

typedef struct {
    uint8_t updateIntervall;
    uint8_t prio;
    uint8_t reg_cnt; // 建议新增成员存储数组长度,后续使用时避免越界
    Registers *regs;
} Config;

int main(void) {
    uint8_t amount = 4;
    Config cfg = {0}; // 建议初始化结构体所有成员为0,避免野值
    // 分配amount个Registers元素的空间
    cfg.regs = malloc(amount * sizeof(Registers));
    if (cfg.regs == NULL) {
        // 内存分配失败处理逻辑
        return -1;
    }
    cfg.reg_cnt = amount; // 存储数组长度
    
    // 使用示例:给第0个寄存器赋值
    cfg.regs[0].reg = 0x1234;
    // 小端平台下此时cfg.regs[0].low = 0x34,cfg.regs[0].high = 0x12
    
    // 使用完必须手动释放内存,避免泄漏
    free(cfg.regs);
    cfg.regs = NULL;
    cfg.reg_cnt = 0;
    
    return 0;
}

可选优化:柔性数组

如果你想要减少一次内存释放操作,也可以用C标准支持的柔性数组实现,结构体最后一个成员定义为长度为0的数组,分配时直接给整个结构体加数组的总大小分配即可:

typedef struct {
    uint8_t updateIntervall;
    uint8_t prio;
    uint8_t reg_cnt;
    Registers regs[]; // 柔性数组成员,必须放在结构体最后
} Config;

// 分配逻辑
uint8_t amount = 4;
Config *cfg = malloc(sizeof(Config) + amount * sizeof(Registers));
if (cfg == NULL) {
    return -1;
}
cfg->reg_cnt = amount;

// 使用方式和之前一致
cfg->regs[0].reg = 0x1234;

// 释放时只需要释放一次cfg即可
free(cfg);

注意事项

  • 动态分配的内存使用完必须手动释放,否则会出现内存泄漏
  • 访问数组成员前建议判断索引是否小于存储的数组长度reg_cnt,避免越界访问
  • 分配内存后一定要判断返回值是否为NULL,处理分配失败的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:54:04