In-depth memory alignment _c language

Source: Internet
Author: User
Tags pack

1. Intro

In a structure, the compiler allocates space for each member of the struct according to its own natural bounds (alignment) condition. Each member is stored sequentially in memory in the order in which they are declared, with the address of the first member the same as the address of the entire structure.

For example, the following structure member space allocation (assuming alignment is greater than 2 bytes, that is, #pragma pack (n), n = 2,4,8 ...) is discussed below #pragmapack ()):

Copy Code code as follows:

struct test
{
Char X1;
Short X2;
Float X3;
Char x4;
};

The first member of the structure, X1, has an offset address of 0, which occupies the 1th byte. The second member, X2, is Short type, whose starting address must be 2 bytes to the bounds, that is, the offset address is a multiple of 2. Therefore, the compiler populates a null byte between X2 and X1, placing the X2 at the offset address of 2. The third member of the structure, X3, and the fourth member X4 happen to be on their natural alignment address, and no additional padding bytes are required before them. In the test structure, member X3 requires 4 bytes to the bounds, is the largest bounding unit required by all members of the structure., so the natural boundary condition of test structure is 4 bytes, The size of the entire structure is an integral multiple of the maximum size of the bounding cell (this rule is also followed in the structural body of the structure, as described below)., the compiler fills in 3 empty bytes after member X4. The entire structure occupies 12 bytes of space.
about why you want to align the memory, reference < parse the memory alignment Data Alignment:straighten up and fly Right's detailed >. Reading this article will make it easier to understand the following content.

Okay, here's the #pragma pack:

2. #pragma pack ()

The preprocessing directive is used to change the alignment parameters. By default, the C compiler allocates space for each variable or data unit according to its natural boundary condition. Generally, you can change the default alignment parameters by using the following methods:

· Using pseudo-directive #pragma pack (n), the C compiler is aligned according to n bytes.

· Use the pseudo Directive #pragma pack () to cancel the custom byte alignment.

Can also be written as:

#pragma pack (push,n)

#pragma pack (POP)

#pragma pack (n) indicates that the alignment unit for each member is not greater than N (an integer power of n 2). This provides an upper bound that affects only members with a snap cell greater than N, and has no effect on members that are not more than n on the aligned byte. Actually literally, pack is "parcel, pack" meaning, #pragma pack (n) stipulates n bytes is a "parcel", the individual thinks that really do not understand words can think the processor can read/write n bytes from memory at one time, so good understanding. For members that are smaller than N, of course, they are aligned according to their alignment conditions, because they can be taken out at once, regardless of their size. For members with an alignment condition that is greater than n bytes, the members are aligned to their own alignment and need the same number of reads in N-byte alignment, but they save space according to the N-byte alignment. You can refer to the < parsing memory alignment I mentioned above in the detailed > of the right of the alignment:straighten up and fly. Here is a Daniel's point of view, and I say is a meaning:

All the It means is this each member of it would require alignment no greater than n.it doesn ' t mean that each member would have Alignment requirement N.notice, after all, it's called pack and not align for a reason--precisely because it controls PA cking, not alignment.

In addition, GNU C also has one of the following ways:

· __ATTRIBUTE__ ((aligned (n)) to align the member of the structure to the N-byte natural boundary. If the length of a member in the structure is greater than N, it is aligned according to the length of the maximum member.

· __ATTRIBUTE__ ((packed)), cancels the optimized alignment of the structure during compilation, and aligns to the actual number of bytes occupied.

The above n = 1, 2, 4, 8, 16 ... The first approach is more common.

3. How members of the structure body find their place

First, follow these rules:

1. Each member takes its own alignment and the smaller value of the alignment parameter specified by the #pragma pack as its own alignment.

2. the alignment of a complex type, such as a struct, is the alignment used when the type declaration, or the maximum value of the alignment parameter used by all its members at the time of declaration, and the minimum of the alignment parameters specified by the #pragma pack at this time. That's what Daniel said:

The documentation for #pragma pack (n) says that "the alignment of a ' is ' to be ' on a boundary this is either a Multiple of n or a multiple of the size of the member,whichever is smaller ". However I is incorrect; The docs should say that the alignment of a and would be on a boundary this is either a multiple of n or the alignment R Equirement of the, whichever is smaller.

3. the length of the alignment must be an integer multiple of the largest alignment parameter (not the size of the member) in the member, so that each entry is guaranteed to be aligned when the array is processed.

4. for arrays, such as: Char a[3]; this way, its alignment is the same as writing 3 chars, respectively. That means it's still aligned in 1 bytes.

If write: typedef char ARRAY3[3];

Array3 This type of alignment is still aligned to 1 bytes instead of its length.

5. regardless of the type, the aligned boundary must be 1,2,4,8,16,32,64 .... One of the.

Look at a simple example:

Copy Code code as follows:

#pragma packs (8)
struct S1
{
Short A;
Long B;
};
struct S2
{
char c;
S1 D;
Long long E;
};
#pragma pack ()

There is an important condition for member alignment: Each member is aligned separately. That is, each member is aligned in its own way.

This means that although the above specifies a 8-byte alignment, not all members are aligned in 8 bytes. The rule for its alignment is that each member is aligned to the smaller of its type's alignment parameters (usually the size of this type) and the specified alignment parameter (here is 8 bytes). And the length of the structure must be an integer multiple of all the alignment parameters used (as long as it is the integer multiple of the maximum alignment parameter), not enough to fill the empty byte (depending on the compiler).

In S1, member A is 2 bytes by default in 2-byte alignment, and the specified alignment parameter is 8. The two values are 2,a by 2-byte, member B is 4 bytes, the default is 4-byte alignment, then 4-byte alignment, and a after 2 bytes to store B, so sizeof (S1) should be 8. 8 is a multiple of 4, which satisfies the 3rd rule above.

In S2, like a in C and S1, 2-byte alignment, and D is a struct, which is 8 bytes, and what does it align? For a struct, its default alignment is the largest of the alignment parameters used by all its members when the struct is defined (declared), and the S1 is 4, less than the specified 8. So member D is aligned by 4 bytes, c after 2 bytes, followed by a 8-byte structure D. Member E is 8 bytes, which is aligned to 8 bytes by default, as specified, so it is on the 8-byte boundary, at which point 12 bytes have been used, so D is then filled with 4 bytes, and the member E is placed from the 16th byte. At this point, the length is 24 and can already be divisible by the maximum alignment parameter 8 (Member e aligned to 8 bytes). In this way, 24 bytes were used altogether.

It 's not complicated enough? One more:

Copy Code code as follows:

#pragma packs (4)
struct S1
{
Char A;
Double b;
};
#pragma pack ()

#pragma packs (2)
struct S2
{
char c;
struct S1 st1;
};
#pragma pack ()


#pragma packs (2)
struct S3
{
Char A;
Long B;
};
#pragma pack ()

#pragma packs (4)
struct S4
{
char c;
struct S3 St3;
};
#pragma pack ()

First look at the s1,a position at the offset address of 0 (the first byte). B default 8-byte alignment, but the specified alignment parameter is 4 bytes, so B is aligned to 4 bytes, placed at the offset address 4, and a after 3 bytes. So sizeof (S1) is 12. The alignment parameter of the structure body S1 is 4, which is used below.

Then look at the s2,c placed in the first byte. ST1 own alignment parameter is 4, but the alignment parameter specified at this time is 2, so st1 is aligned to 2 bytes, and C is followed by a word after the st1. Note that the inside of the ST1 will not change, the declaration of S1 is what it is, because we have to ensure that sizeof (s2.st1) = = sizeof (S1), if not this chaos. Such sizeof (S2) is 14. The alignment parameter of the structure body s2 is an integer multiple of 2,14 2.

Then look at the S3,a placed in the first byte. B default 4-byte alignment, but the specified alignment parameter is 2, so B is aligned to 2 bytes, placed at the offset address of 2, and a after a byte. sizeof (S3) is 6. The alignment parameter of the structure body S3 is 2 (used later), and 6 is the integer multiple of 2.

Finally look at the S4,c placed in the first byte. ST3 's own alignment parameter is 2, the specified alignment parameter is 4, so st3 takes a minimum value, snaps to 2 bytes, places the offset address at 2, and a byte after C. The sizeof (S4) is 8, and the alignment parameter of the struct is 2,8 as an integer multiple of 2.

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.