为何S_t结构体大小为4?柔性数组未统计且内存重叠?
问题解析与解决说明
一、结构体大小仅为4字节的原因
你代码里的S_t结构体肯定是用了柔性数组成员,定义应该类似这样:
typedef struct { uint32_t len; char data[]; } S_t;
C语言里的柔性数组有个关键特性:它必须是结构体的最后一个成员,而且sizeof计算结构体大小时,完全不会把柔性数组的空间算进去,只会统计前面所有成员的总大小——这里就是uint32_t的4字节,所以你看到的结果是4。柔性数组本身更像一个“内存占位标记”,不占用结构体自身的内存。
二、内存地址重叠的原因
你定义的外层结构体(比如Out_t)应该是把S_t和char data[8]放在了一起,比如:
typedef struct { char data[8]; S_t S; } Out_t;
或者反过来的结构。当你声明Out_t out;后:
out.S的大小只有4字节(只包含len),out.S.data作为柔性数组的指针,会直接指向out.S结构体末尾之后的内存地址。- 而这个“末尾之后”的地址,正好就是外层结构体里
char data[8]所在的内存区域(或者反过来,取决于结构体成员的顺序),所以out.data和out.S.data会指向同一块内存,出现重叠。
柔性数组的正确用法
如果要给柔性数组分配独立的内存空间,必须用动态内存分配:
// 分配结构体本身的4字节 + 8字节的数组空间 S_t *s = malloc(sizeof(S_t) + 8); if (s == NULL) { // 处理分配失败 } s->len = 8; // 此时s->data指向的是malloc额外分配的8字节空间,不会和其他内存重叠
内容的提问来源于stack exchange,提问作者Hamzahfrq
相关产品推荐
相关产品推荐

