C语言 联合的内存分配如何发生[重复]

q5iwbnjs  于 2023-04-19  发布在  其他
关注(0)|答案(2)|浏览(111)

此问题已在此处有答案

Why isn't sizeof for a struct equal to the sum of sizeof of each member?(13个回答)
6天前关闭。
下面是我的代码

#include <stdio.h>
#include <stdint.h>

union myUnion {
    struct {
        uint8_t a1;
        uint8_t b1;
        uint8_t c1;
        uint8_t d1;
        uint8_t e1;
    } abc;
    int a;
};

int main() {

    printf("size:%ld\n", sizeof(union myUnion));

    return 0;
}

输出:

规格:8
这里为什么联合的大小是8,结构有5个成员,总共5byte,int是4byte,因此大小应该是9,正确的,为什么大小返回8?
试图理解内存分配是如何发生的

46scxncf

46scxncf1#

这个结构有五个单字节成员,所以它需要五个字节。int可能需要四个字节。所以联合需要这五个字节中较大的一个,即五个字节。
然而,每个对象的大小必须是其对齐要求的倍数,因此,如果我们将它们组成一个数组,数组的每个元素都从其所需的对齐开始。int可能有四个字节的对齐要求。它在联合体中,因此联合体必须至少有四个字节的对齐要求。
所以联合体的大小必须是4字节的倍数。5字节不是4字节的倍数。因此,为了使联合体的大小成为4字节的倍数,编译器添加了三个未使用的字节,称为填充,以使大小为8字节,这是4字节的下一个倍数。

c2e8gylq

c2e8gylq2#

C编译器填充了你的并集。参见6.7.2.1,第18和19段:
联合体的大小足以包含其最大的成员。任何时候,最多一个成员的值可以存储在联合体对象中。一个指向联合体对象的指针,经过适当的转换后,指向它的每个成员(或者如果成员是位字段,则到其驻留的单元),反之亦然。联合对象的成员以这样一种方式重叠,即指向它们的指针在转换为指向字符类型的指针时指向同一个字节。在联合对象的末尾可能有未命名的填充,但在其开头没有。
在结构或联合的末尾可能有未命名的填充。
gcc(和其他)支持类型属性的扩展。你可能特别感兴趣的是packed属性:

#include <stdio.h>
#include <stdint.h>

union myUnion {
    struct {
        uint8_t a1;
        uint8_t b1;
        uint8_t c1;
        uint8_t d1;
        uint8_t e1;
    } abc;
    int a;
} __attribute__((packed));

int main() {
    printf("size:%ld\n", sizeof(union myUnion));
    return 0;
}

现在它将返回:

size:5

相关问题