preface

The so-called foundation is not firm, the earth shakes. As an Android developer, I have some NDK development experience, but when WRITING C or C++ code, I always feel like I don’t know why.

With the possibility of using a large amount of C/C++ code in the subsequent project, the author realized that it was necessary to consolidate the foundation of C/C++ and sweep up the knowledge blind spots left by the previous LEARNING of C/C++.

I may update some brief notes on reviewing C/C++ from time to time. These notes are more about my own understanding of a certain knowledge point in the process of reviewing. If there is any mistake, please show mercy.

Byte alignment

Structure size calculation is a basic C/C++ interview must ask. So how do you calculate the size of a structure? Is it a simple sum of member variable sizes?

Obviously not, but let’s take a quick look at the concept of byte alignment before we get into struct sizing.

In order to improve the efficiency of accessing data, the CPU uses a strategy of byte alignment. So what is byte alignment?

Byte alignment puts a limit on the starting address of each variable of the underlying data type: the starting address of each variable must be an integer multiple of the size of the variable. For example, a variable of type int, which is 4 bytes long, should start at a multiple of 4, so it should start at an address like 0x00000000 or 0x00000004 or 0x00000008.

Structure size calculation

Here’s an example:

// Struct byte alignment problem, is the following struct 5 bytes? Struct DataA{char a; struct DataA{char a; int b; }; // How many bytes is the DataB? Or 8 bytes. Why? struct DataB{ char a; char c; int b; }; // How many bytes is the DataB? 12 bytes, why? struct DataC{ char a; int b; char c; };Copy the code

The size of a structure depends not only on the type of the variable, but also on the order of the variables. For example, the DataB and DataC structures start with the order of the variables. Why do they take up more bytes?

Let’s analyze them one by one:

First, for DataA char variable A, which takes up 1 byte, the byte alignment rule dictates that its address be 0x00000000. For int variable B, which takes up 4 bytes, the byte alignment rule dictates that its address be a multiple of 4. But address 0x00000000 is already occupied by variable A, and addresses 0x00000001 to 0x00000003 do not conform to the alignment rules, so the addresses of variable B are 0x00000004 to 0x00000007. What about the empty addresses 0x00000001 to 0x00000003? The address of the DataA structure is 0x00000000 to 0x00000007, which is 8 bytes in size.

For DataB, char variables A and C are 1 byte, so their addresses are 0x00000000 and 0x00000001 according to byte alignment rules. For int variables B, since it takes 4 bytes, So its address is 0x00000004 to 0x00000007 as DataA, so DataB is also 8 bytes in size.

What about DataC? First of all, if we remove the c variable of DataC, it is the same as the structure DataA, which is 8 bytes in size. What if we add the c variable of type char? Since char is one type of byte, isn’t DataC nine bytes? How did it get to 12 bytes?

This is because there is another rule in struct size calculation: the total byte size is an integer multiple of the number of bytes of the largest member variable type.

Since the largest DataC member type is int, it takes up 4 bytes, so the total size should be a multiple of 4. Previously, the size of DataC should be 9, but 9 is not a multiple of 4, so the size of DataC byte 9 should be a multiple of 4, so the size of DataC byte 9 should be 12 bytes.

Calculation of the size of the structure nesting

In the following example, how to calculate the size of the DataD structure is 40 bytes?

// 40 bytes. struct DataD{ char a; int b; char c; double d; struct DataC data; };Copy the code

The largest variable type for DataD is double, which takes up 8 bytes, so the total size must be a multiple of 8. Add the address of char a to 0x00000000, then the address of int B to 0x00000004 to 0x00000007, and the address of char C to 0x00000008, according to byte alignment rules. A variable of type double, d, should have an address of 0x00000016 to 0x00000023 according to the byte-size alignment rule, i.e. 0x00000009 to 0x00000015 should be filled with empty data.

So so far if you don’t count the size of the variable data the structure DataD is 24 bytes, and I already know that the size of the variable DataC is 12 bytes, and since the type of the variable data is a structure, not a basic data type, So the size of the structure DataD should be 24 plus the size of the structure DataC which is 24+12=36 bytes, but 36 is not a multiple of 8, so the total size of the structure DataD should be 40.

conclusion

1. Bytes are aligned according to the largest bytes occupied by the basic data type of the member variable, that is, the total size must be an integer multiple of the byte size occupied by the largest basic data type; 2. Use only base datatypes. For example, in the previous example, the largest base DataD is double, not DataC. 3. The starting address of each member variable is an integer multiple of the memory occupied by the variable type. If it is insufficient, the insufficient part is filled with empty data to an integer multiple of the memory occupied by the variable type.

Pay attention to me, progress together, life is more than coding!!