The introduction

Let’s start with an interesting example, and think about its size

In the problem diagram, there are two structural variables, P1 and P2, whose member variables are the same, except that the structural order is different. Do p1 and p2 have the same sizeof memory? How many should I output? Are they all 15 bytes in size?

The answer Come on, is there a black question mark? So, from this example, we can derive two questions:

1. Why is the size of P1 16 instead of 15? 2. Why is the size of P2 24, and is neither equal to 15 nor equal to 16?Copy the code

Don’t panic, we will answer one by one!

Memory alignment

When allocating memory to structures and their member variables, the OC follows three content alignment principles, which are used to maximize CPU memory reading speed and thus improve code performance.

Rule 1: Member variable alignment rules

In a struct or union, the first member (in the order in which the code is written) is stored at the beginning of the variable address of the structure (offset is 0) and occupies the size of the member’s memory space. The subsequent members are stored in sequence, but their storage starts at an integer multiple of offset.

What does that mean? Here’s an example, above! Take the structure test2 in the introduction for example:

struct test2 { double p1; // 8 bytes char p3; // 1 byte int p2; // 4 bytes short p4; // 2 bytes}Copy the code

Let’s say we have 24 bytes of memory for test2. Let’s see what it looks like. First, an empty row of addresses

And then the first thing that comes in is double P1. As a rule, it will start storing 8 bytes (double) at offset 0, resulting in the following result

Then store the next member, char P3. Then, according to the principle, we first determine whether the offset of the next empty space is an integer multiple of the size of p3 bytes. The following offset is 8 and the size of p3 is one byte. The storage condition is met and the result is as follows

We then proceed to store the next member, int P2. Char p3: Is 9 a multiple of 4? Apparently not. By analogy, we will choose the position whose offset is 12 to start the storage, as follows

And so on, the structure of the final storage is as follows

Ok, that’s it. However, it seems that something is not right. We only stored 18 bytes [0-17], so why is the size of the final print 24? What happened to 18-23? Is it just empty? Yeah, that’s right. It’s empty. This leads to the second rule structure size alignment rule

Rule 2: Structure size alignment rule

The size of a structure variable must be an integer multiple of the size of the member variable that occupies the most space.

What does that mean? Let’s continue with the example above. Test2 members occupy positions [0-17]. Is 18 an integer multiple of 8 occupied by the largest double p1 member? Struct test2 (24 bytes); struct test2 (15 bytes);

What about rule number three?

Rule three needs another example, so let’s move on

Rule 3: Structure nesting alignment rule

If a structure has member variables of the structure type, which form a nested relationship, the structure members are stored at integer multiples of the size of the largest member variable in the structure. The structure size is also aligned to integer multiples of the size of the largest storage member in the nesting relationship.

So without further ado, let’s look at a struct test3

struct test3 {
    double p1;
    int p2;
    char p3;
    short p4;
    int p5;
    test2 p6;
}
Copy the code

If you’re interested, you can try it yourself, and here we go straight to conclusion 48. All right, so let’s see what this looks like in terms of a comprehensive version of the three rules. First, we will quickly go through the storage of non-structure members as follows

Where does test2 P6 start? By rule, the largest member in test2 p6 is a double (8 bytes), which is an integer multiple of 24, so it starts at position 24 and is stored at the beginning of the rule, so we quickly iterate through it

Finally, the resulting structure’s internal storage size is aligned to integer multiples of the largest member of its nested relationship. In this case, the largest is double, which is 8 bytes, so align it by multiple integers of 8, and the resulting size is 48. At this point, take work. The structure’s memory storage is basically clear.

thinking

I do not know if there is a small partner will have such a question

Do we need to pay attention to the order in which attributes/member variables are declared?Copy the code

So, stay tuned for the next article, “Objc Below the Surface — Class Attribute/Member Variable Rearrangement.”