结构体与内存对齐

2020-09-09  本文已影响0人  Y丶舜禹

什么是内存对齐?

内存对齐,简单来说就是编译器为了节省查找内存时间,通过一定的算法将数据按照规律存储,而不是一个一个的紧密排列,每个平台上的编译器都有自己的“对齐系数”(一般为4和8),而iOS的对齐系数为8即8字节对齐

下表是各种数据类型在iOS中的占用内存大小,根据对应类型来计算结构体中内存大小


常见数据类型大小
获取内存常见的三种方式

获取内存大小的三种方式分别是:

下面以一段代码为例

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        NSObject *object = [[NSObject alloc]init];
        NSLog(@"%lu - %lu - %lu",sizeof(object),class_getInstanceSize([NSObject class]),malloc_size((__bridge const void *)(object)));
        
    }
    return 0;
}

运行后的输出为:8 - 8 - 16

解释:
sizeof:可用于获取类、结构、共用体和其他用户自定义数据类型的大小。
class_getInstanceSize:返回类实例的大小。
malloc_size:返回实际给定的内存大小

结构体内存对齐

接下来,我们首先定义两个结构体,分别计算他们的内存大小,以此来引入今天的正题:内存对齐原理

//1、定义两个结构体
struct Struct1{
    char a;     //1字节
    double b;   //8字节
    int c;      //4字节
    short d;    //2字节
}Struct1;

struct Struct2{
    double a;   //8字节
    int b;      //4字节
    short c;    //2字节
    char d;     //1字节
}Struct2;


//计算 结构体占用的内存大小
NSLog(@"%lu-%lu",sizeof(Struct1),sizeof(Struct2));

以下是输出结果

结果

从打印结果我们可以看出一个问题,两个结构体除了变量顺序一样之外,其他几乎完全一致,那么他们的大小为什么内存大小不相等呢?这就是内存对齐现象。

内存对齐规则

内存对齐规则有一下三点:

验证对齐规则

结构体Struct1 内存大小计算

根据内存对齐规则计算Struct1的内存大小,详解过程如下:

因此Struct1的需要的内存大小为 18字节,而Struct1中最大变量的字节数为8,所以 Struct1 实际的内存大小必须是 8 的整数倍,18向上取整到24,主要是因为24是8的整数倍,所以 sizeof(Struct1) 的结果是 24

结构体Struct2 内存大小计算

根据内存对齐规则计算Struct2的内存大小,详解过程如下:

因此Struct2的需要的内存大小为 15字节,而Struct2中最大变量的字节数为8,所以 Struct2 实际的内存大小必须是 8 的整数倍,15向上取整到16,主要是因为16是8的整数倍,所以 sizeof(Struct2) 的结果是 16

内存情况如下图:

结构体对应的存储情况
结构体嵌套结构体

上面的两个结构体只是简单的定义数据成员,下面来一个比较复杂的,结构体中嵌套结构体的内存大小计算情况

//结构体嵌套结构体
struct Struct3{
    char a;     //1字节
    double b;   //8字节
    int c;      //4字节
    short d;    //2字节
    struct Struct2 e;//24字节
}Struct3;

//2、打印 Struct3 的内存大小
NSLog(@"Struct3内存大小:%lu", sizeof(Struct3));
NSLog(@"Struct3中结构体成员内存大小:%lu", sizeof(Struct3.e));

打印的结果如下所示


Snip20200909_4.png

因此Struct3的需要的内存大小为 24+16=40字节。

Struct3内存情况如下图:

Struct3内存

以上便是结构体与内存对齐的全部内容,如有错误内容,还请多多包涵。

上一篇 下一篇

猜你喜欢

热点阅读