如何为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
相关产品推荐
相关产品推荐

