Memory alignment in C + +

Source: Internet
Author: User
Tags processing instruction

(32bit,x86 environment, VS2010)

struct test

{

Char M1;

unsigned int m2;

char m3;

Double M4;

Char M5;

};

To execute sizeof (test), get a value of 32, and we take the inside of each variable sizeof, really is the size of the owning type, but why not 1+4+1+8+1=15, we execute the following code to calculate the address offset between each variable:

Test T;

cout << sizeof (t) << Endl;

cout << (unsigned int) (void*) &t.m2-(unsigned int) (void*) &t.m1 << Endl;

cout << (unsigned int) (void*) &t.m3-(unsigned int) (void*) &t.m2 << Endl;

cout << (unsigned int) (void*) &t.m4-(unsigned int) (void*) &t.m3 << Endl;

cout << (unsigned int) (void*) &T.M5-(unsigned int) (void*) &t.m4 << Endl;

The output is as follows

32

4

4

8

8

This is because the structure body is allocated with its own alignment rules, and the default rules for the structure body-in-memory alignment are as follows:

1. The order in which memory is allocated is in the order of Declaration.

2, the offset of each variable relative to the starting position must be an integer multiple of the size of the variable type, not an integer multiple empty memory, until the offset is an integer number of times.

3. The size of the entire structure must be an integer multiple of the maximum value of the variable type inside.

Analyze the test structure above

1, allocate M1, at this time offset is 0, integer times, allocate 1 bytes

2, the allocation of M2, at this time the offset of 1,int type size is 4, not an integer multiples, so first skip 3 bytes, at this time the offset is 4, an integer multiple, allocating m2 four bytes, so this step is allocated 7 bytes

3, allocate M3, at this time the offset is 8,m3 only need 1 bytes, integer times, allocate 1 bytes

4, the allocation of M4, at this time the offset of 9,double type is 8 bytes, not an integer multiple, the next integer is 16, so skip 7 bytes, and then allocate M4, the step is allocated 15 bytes.

5, the allocation of M5, at this time the offset is 24, is an integer multiple, allocated 1 bytes

6, at this time altogether allocated 25 bytes, but the total size if the maximum type size of the integer times, double is the maximum type, is 8, the most recent is 32, so the step to allocate 7 bytes.

Of course, above is just the compiler default allocation rules, we can change the size of the structure by the following methods

1, change the structure of the variable declaration order, according to the type size from small to large declaration, occupy space will be relatively small.

2, we can use #pragma to modify this rule, #pragma是C + + a pre-processing instruction, it has many functions, one of the role is to modify the allocation rules. Before the struct definition of the above code is added:

#pragma pack (1)

The operation results are as follows

15

1

4

1

8

Change to #pragma pack (2) as follows

18

2

4

2

8

After adding the #pragma pack (n), the rule becomes the following:

1, offset if n and the current variable size of the small value of an integer multiple

2, the overall size if n and the maximum variable size of the small value of an integer multiple

3, the N value must be 1,2,4,8 ..., for other values when you follow the default allocation rules

Note: In fact, the first example is also according to this rule, but it is using the system default N value, the default is 8,vs in the path is project]| [settings],c/c++ tab category of the Code generation option of the struct Member Alignment.

Common usage of #pragma pack is as follows

1. #pragma pack (push, N)//Set the current alignment value to N and save the previous alignment value to the stack

2, #pragma pack (n)//Set the current alignment value to N, do not save the previous value

3. #pragma pack ()//restores the current alignment value to the default 8

4, #pragma pack (POP)//If the stack has a value, the stack top value out of the stack and set to the current value, there is no value in the stack is not changed

5, #pragma pack (pop, N)//If the stack has a value, the stack top value out of the stack, the current alignment value is set to n

In addition to structs, unions and classes are the same.

Why to align, the modern computer memory space is divided according to Byte, theoretically, it seems that the access to any type of variable can start from any address, but the actual situation is to access certain variables at the time of a particular memory address access, which requires all types of data in accordance with a certain rules in the space arrangement, Instead of sequentially one by one emissions, that's the alignment. The effect and reason of alignment: the processing of storage space varies greatly with each hardware platform. Some platforms can only access certain types of data from certain specific addresses. Other platforms may not have this, but the most common is the loss of access efficiency if the data storage is not aligned as appropriate for its platform requirements. For example, some platforms each read from an even address, if an int (assumed to be 32-bit system) if it is stored at the beginning of the even address, then a read cycle can be read out, and if it is stored in the location of the odd address, it may require 2 read cycles, And the high and low bytes of the two read results are pieced together to get the int data. Obviously, the reading efficiency is much lower. This is also the game of space and time. Generally, when we write programs, we do not need to consider alignment issues. The compiler chooses the alignment strategy for the target platform for us.

Many of the pitfalls of alignment in code are implicit. For example, when forcing type conversions. For example:

unsigned int i = 0xFFFFFFFF;

cout << hex << i << Endl;

char *p = NULL;

unsigned short *p1=null;

p= reinterpret_cast<unsigned Char *> (&i);

p= (char *) (&i);

*p=0x00;

cout << hex << i << Endl;

p1= (unsigned short *) (p+1);

*p1=0x0000;

cout << hex << i << Endl;

The output is as follows

Ffffffff

Ffffff00

ff000000

The last two lines of code, from the odd boundary to access the Unsignedshort variable, clearly do not conform to the rules of alignment.

Memory alignment in C + +

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.