struct 结构体变量的内存分配

我们先定义一个结构体

typedef struct {
    uint32_t  num0;    // 4 bytes
    uint16_t  num1;    // 2 bytes
    uint16_t  num2;    // 2 bytes
    uint32_t  num3;    // 4 bytes
    uint64_t  num4;    // 8 bytes
}header;

为了形象的理解内存,把内存想象成一个矩形,其中每一个bit都是一个微小的矩形,例如16k的内存条(即2^13bytes) 想象成‘长x宽 = 2^7 x 2^6byte’ 或者’2^8 x 2^5byte’这样子

内存的分配就向平原地区的农田一样
like that
struct 结构体变量的内存分配_第1张图片

当然因为每个结构体的大小可能不同,并不是每块被分配的内存空间都一样大。

以header为例,占字节数最长的成员为8bytes的num4,那么这个结构体在内存中的长就是8bytes
至于他有多宽才能装得下这个结构体,并且达到最优的空间利用率呢?(分配的空间尽可能的小)
struct 结构体变量的内存分配_第2张图片

我们发现 sizeof(num0) + sizeof(num1) + sizeof(num2) = 8bytes
于是上面的图就变成下面这样:
struct 结构体变量的内存分配_第3张图片

还剩下num3没有分配坑,至于它放在哪里就显而易见了吧
于是,这个struct在内存中的结构如下图:
struct 结构体变量的内存分配_第4张图片
现在请问这个矩形所占用的内存空间是大?
当然,这里不需要去考虑剩下那一块蓝色的空白,虽然没有使用,但它确实属于这个struct

于是,综合以上分析,得:sizeof(header) = 3 x 8 = 24bytes


对一个结构体的分析也许不能深入理解,下面我们再来一个

typedef struct {
    uint16_t  num0;    // 2 bytes
    uint64_t  num1;    // 8 bytes
    uint16_t  num2;    // 2 bytes
    uint32_t  num3;    // 4 bytes
    uint32_t  num4;    // 4 bytes
}header1;

如果struct长这个样,系统会怎样给他分配内存呢?

我们依然从占用字节数成员开始,最大的num1占8bytes
因此这块内存空间的长依然是8bytes,如下图:
struct 结构体变量的内存分配_第5张图片
其他成员的位置实际上如下图:
struct 结构体变量的内存分配_第6张图片

于是,综合以上分析,得:sizeof(header1) = 4 x 8 = 32bytes


实际上看header和header1,他们的成员变量类型以及每个类型对应的变量数量是相同的,但是实际上它们占用的内存大小却不一样。这说明了结构体的成员变量先后顺序影响着其内存分配。因此为了达到最优的空间利用率,定义结构体的时候成员变量的位置是有必要多加斟酌的。

你可能感兴趣的:(iOS)