Z/C + + memory alignment ZZ

Source: Internet
Author: User

This article is very easy to read in layman's words. Recommended. The picture needs to look at the original Bo.

http://songlee24.github.io/2014/09/20/memory-alignment/

here is a written question of NetEase: struct { uint32_t m1; char m2; } varray[2];which of the following judgments must be established? (multiple selection)
    1. sizeof(varray[0]) == 5
    2. sizeof(varray[0]) == 8
    3. (void*)&(varray[0].m1) < (void*)&(varray[0].m2)
    4. (char*)&varray[0] == (char*)&(varray[0].m1)
    5. (char*)&varray[0] + sizeof(varray[0]) == (char*)&varray[1]
    6. (char*)&(varray[0].m2) + 1 == (char*)&varray[1]
    7. (char*)&(varray[0].m2) + 4 == (char*)&varray[1]

This topic examines the memory alignment knowledge point, after reading this article you know this question should choose what.

First, what is memory alignment

memory Alignment, also called byte alignment.

The memory space in modern computers is divided by Byte, in theory it seems that access to any type of variable can start from any address, but the reality is that when accessing a particular type of variable, it is often accessed at a specific memory address, which requires all types of data to be spatially arranged according to certain rules, Instead of sequentially one by one emissions, that's the alignment.

For a simple example, uint32_t the total memory space is 4 bytes, which char is 1 byte. If you put them in a struct, the memory space should be 4 + 1 = 5 bytes. In fact, in VS2012 and GCC environments, the results of sizeof operations are 8 bytes:

1
2
3
4
5
6
7
8
9
10
11
12
13
struct
{
uint32_t M1; #include <stdint.h>
char m2;
}varray;

int main ()
{
printf ("%d\n", sizeof (VARRAY.M1)); Output 4
printf ("%d\n", sizeof (VARRAY.M2)); Output 1
printf ("%d\n", sizeof (Varray)); Output 8
return 0;
}

Illustration:

Here is an aligned unit with 4 bytes.

Second, why the memory alignment

There are two reasons why memory alignment is possible:

    • platform Reason : Each hardware platform on the storage space processing has a very big difference. Some platforms can only access certain types of data from certain specific addresses. ————-For example, some architectures have errors when accessing a variable that is not aligned, so programming must ensure byte alignment in this architecture.

    • Performance Reason : Memory alignment can improve access efficiency. ————-For example, some platforms read each time from the even address, if an int (assuming a 32-bit system) if it is stored at the beginning of the location of the even address, then a read cycle can be read out of the 32bit, and if it is stored at the beginning of the odd address, it takes 2 read cycles, The 32bit data can be obtained by piecing together the high and low bytes of the two read-out results.

Three, the rules of alignment

Compilers on each particular platform have their own default "alignment factor" (also known as the number of Zimo). You can change this factor by precompiling the command #pragma pack(n) , n=1,2,4,8,16, where n is the "alignment factor" you want to specify.

1) Concept:

Valid Alignment value : is the #pragma pack smaller of the specified value and the longest data type length in the struct. Valid alignment values are also called snap units .

Note: VS, VC default is #pragma pack (8), and GCC is #pragma pack (4) By default, and GCC only supports 1,2,4 alignment.

2) Rules:

    1. The first address of a struct variable is an integer multiple of a valid alignment value (alignment unit).

    2. The offset of the first member of the struct is 0, and the subsequent offset of each member relative to the first address of the struct is an integer multiple of that member's size and the smaller of the valid alignment values, and if necessary the compiler adds padding bytes between the members.

    3. The total size of the struct is an integer multiple of the valid alignment value, and if necessary the compiler will add padding bytes after the last member.

    4. Continuous elements of the same type within a struct will be in contiguous spaces, and arrays.

Here are a few examples to help understand (test environment is VS2012):

Example one:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21st
22
23
24
25
26
27
28
struct
{
int i; 4 bytes
Char C1; 1 bytes
char C2; 1 bytes
}x1;

struct
{
Char C1; 1 bytes
int i; 4 bytes
char C2; 1 bytes
}x2;

struct
{
Char C1; 1 bytes
char C2; 1 bytes
int i; 4 bytes
}x3;

int main ()
{
printf ("%d\n", sizeof (x1)); Output 8
printf ("%d\n", sizeof (x2)); Output 12
printf ("%d\n", sizeof (x3)); Output 8
return 0;
}

As you can see, the three structures defined above only exchange the order of member declarations. Because the longest data type in the struct is 4 bytes, and the VS2010 default #pragma pack (8), the valid alignment value (alignment unit) is 4 bytes. According to the first three rules can be drawn to:

Example two:

1
2
3
4
5
6
7
8
9
10
11
12
struct
{
int A; 4 bytes
Char b[6]; 6 bytes
Double C; 8 bytes
}st;

int main ()
{
printf ("%d\n", sizeof (ST)); Output 24
return 0;
}

The longest data type in the structure above is a double of 8 bytes and the default #pragma pack (8) in VS2012, so the valid alignment value (alignment unit) is 8 bytes. According to the first three rules can be drawn to:

The character array char b[6] can be considered as 6 separate char members.

Iv. pragma pack (n)
    • As mentioned above, the pragma pack default values for compilers on different platforms are different. And we can #pragma pack(n) change this pair of coefficients by pre-compiling commands, n=1,2,4,8,16.

    • #pragma pack(n)is to change the layout of the data members in memory by changing the valid alignment values , and the layout of the members in memory does not change if the n value you set does not affect or change the valid alignment value.

The following is a look at 1, 2, 4 byte alignment in case of example one, example two changes:

1-byte alignment: #pragma pack (1)

At this point the valid alignment values (SNAP units) are 1 bytes, and according to the alignment rules, the members are stored continuously.

The output in example one will change to 6,6,6, such as:

In the example two, the output turns 4 + 6 + 8 = 18:

2-byte alignment: #pragma pack (2)

At this point the valid alignment value (alignment unit) is 2 bytes, then according to the alignment rules, the output of example one will become 6,8,6, such as:

The longest data type in a two-structure case is a double of 8 bytes, so the valid alignment value is 2. At this point the output is still 18, such as:

4-byte alignment: #pragma pack (4)

For example one, the longest data type int in the struct is 4 bytes, so the valid alignment value at this point (the alignment unit) is still 4 and there is no change, so the output is still 8,12,8.

In example two, the original valid alignment value is 8 and now becomes 4. So the output turns 20, specifically:

For 8-byte alignment, 16-byte alignment, here is not an example, I believe that according to the rules of alignment you can easily write it out. It is important to note that some compilers, such as GCC, only support 1,2,4 alignment.





Attached: Answer

Believe to see here, the article at the beginning of the NetEase pen test should be easy to come to the answer. The memory layout of the structure can be clearly illustrated by the memory alignment:

So the answer to the multiple choice should be 2, 4, 5, 7.

The best way to do this type of problem is to draw the aligned memory layout according to the alignment rules, which is simple, clear and error-prone.



Z/C + + memory alignment ZZ

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.