Write in the front: the exploration of the underlying principles of iOS is my usual development and learning in the continuous accumulation of a step forward road. I hope it will be helpful for readers to record my journey of discovery.Copy the code

The directory is as follows:

  1. Exploring the underlying principles of iOS alloc

Summary column for the above

  • Summary of the phase of iOS underlying principle exploration

To prepare

Objective-c, usually written as ObjC or OC, is an object-oriented programming language that extends C. It is primarily used on Mac OS X and GNUstep systems that use the OpenStep standard, and it is the base language for NeXTSTEP and OpenStep.

GCC and Clang have objective-C compilers, and Objective-C compiles on the same systems that GCC and Clang run on.

The objective-C language we develop in daily life will eventually be converted to C/C++ after compilation.

Why study memory alignment of structures? Because as an iOS developer, as we dig deeper into the bottom layer, we know that all objects are a structure at the bottom layer. So how much of the memory space of the structure will be allocated by the system, this question is worth exploring.

First, I stole from Cooci a picture of how much space each data type takes up, which is used as a basis for exploring the principles of structure alignment today.

When we create an object, we don’t need to care too much about the order of the properties, because the system will do the optimization for us. However, when creating the structure, we need to analyze it, because the system does not help us optimize it.

Next, we look at the following two structures:

struct Struct1 {    
    double a;   
    char b;     
    int c;      
    short d;    
    char e;
}struct1;

struct Struct2 {    
    double a;   
    int b;      
    char c;     
    short d;    
    char e;
}struct2;

Copy the code

Double (8 bytes), char (1 byte), int (4 bytes), and short (2 bytes) are of the same type.

printf("%lu--%lu", sizeof(struct1), sizeof(struct2)); -- -- -- -- -- -- -- -- -- -- -- -- 24-16Copy the code

So, this is a problem. Two structures that have the same data type are allocated differently. Why? So that’s what we’re going to focus on today, structural

Memory alignment rules:

1: Data member alignment rules: For struct (or union) data members, the first data member is placed at offset 0, and each data member is stored starting from the size of the member or the size of its children (as long as the member has children, such as arrays, Structure, etc.) (for example, if int is 4 bytes, it starts at the integer multiple address of 4. 2: Struct as members: If a structure has some struct members, the struct members are stored starting at an address that is an integer multiple of the largest internal element size. (struct a contains a char,int,double, etc.) (struct b contains a char,int,double, etc.) (struct a contains a char,int,double, etc.) (b contains a char,int,double, etc.) (b contains a char,int,double, etc.)Copy the code

Then, let’s analyze strucT1 and strucT2 according to the above memory alignment principles:

struct Struct1 { /// 18 --> 24 double a; //8 [0 1 2 3 4 5 6 7] char b; //1 [8 ] int c; //4 [9 [12 13 14 15] short d; //2 [16 17] char e; //1 [18] }struct1; struct Struct2 { /// 16 --> 16 double a; //8 [0 1 2  3 4 5 6 7] int b; //4 [8 9 10 11] char c; //1 [ 12 ] short d; //2 [14 15] char e; // 1 [16] }struct2;Copy the code

Next, let’s look at the structure below

struct Struct3 {    
    double a;           
    int b;              
    char c;             
    short d;            
    int e;              
    struct Struct1 str; 
}struct3;

Copy the code

The output is 48, and the analysis is as follows:

double a; //8 [0 1 2 3 4 5 6 7] int b; //4 [8 9 10 11] char c; //1 [12] short d; //2 [ 14 15 ] int e; //4 [ 16 17 18 19] struct Struct1 str; / / 24 [47] 24...Copy the code

So, the struct3 size is 48.


Guess: What is the size of the internal maximum member in memory alignment?

Let’s check them all out

struct LGStruct4 {          /// 40 --> 48 
    double a;               //8 [0 1 2 3 4 5 6 7]
    int b;                  //4 [8 9 10 11]
    char c;                 //1 [12]
    short d;                //2 [14 15]
    int e;                  //4 [16 17 18 19]
    struct Struct2 str;   //16 [24 ... 39]      
}struct4;
Copy the code

The final size, according to my understanding of the finalization of the memory alignment principle, should be an integer multiple of the size of Struct2 of 16, which is 48. The result, however, was:

    NSLog(@"%lu", sizeof(struct4));
--------
    SMObjcBuild[8076:213800] 40
Copy the code

The maximum member in the structure should refer to double, so let’s verify: 1. The maximum member in the structure should refer to double.

struct Struct2 { ///16 double a; //8 [0 1 2 3 4 5 6 7] int b; //4 [8 9 10 11] char c; //1 [ 12 ] short d; //2 [14 15] }struct2; struct LGStruct4 { /// 24 short d; //2 [0 1] struct Struct2 str; // 16 [8 ... 23] }struct4; The result: 24Copy the code

Because the largest member inside the structure is double which is 8; It’s not an integer multiple of 16 in LGStruct4, so it’s going to be 24.

conclusion

The maximum internal member of a structure refers to the data type inside the structure, so when a structure contains a structure, it is not calculated as an integer multiple of the length of the internal structure.