Memory alignment in C Language

Source: Internet
Author: User
Tags modulus microsoft c

Let's take a look at a specific question:

Memory alignment problems.

 

If struct declares this:
Struct something {
...
...
}

If _ attribute _ (packed) is added to the struct, remember to include the following ";", which is the sum of the strict size of each member.
Alternatively, you can add # pragma pack (n) at the beginning of the program, where N is the number of aligned bytes. If n is 1, it is equal to _ attribute _ (packed )) it means. of course, if # pragma pack (n) is defined after the struct definition, the struct is invalid.

Let's look at a program:
# Include <stdio. h>
// # Pragma pack (1)
Struct node {
// Int I;
Char AA [5];
Int I;
Struct node * front;
Struct node * next;
}; // _ Attribute _ (packed ));
// # Pragma pack (1)

Int main (void)
{
Int;
A = sizeof (char );
Printf ("A = % d", );
A = sizeof (struct node );
Printf ("A = % d", );
Getchar ();
}
Here, _ attribute _ (packed) and # pragma pack (1) are used for alignment. we can see that the struct node * front and struct node * Next both occupy 4 bytes, which is the size of the struct and has no relationship with the form.

The following is an article about the specific structure allocation.

Xu
Many practical computer systems have limits on the locations where basic data is stored in the memory. They require that the first address value of the data be K (usually 4 or 8) this is the so-called memory pair.
And K is called alignment of the data type.
Modulus ). When the ratio of the alignment modulus of one type of S to the alignment modulus of another type of T is an integer greater than 1, we call it the alignment requirement of type s stronger than that of T (strict ), t is weaker than S (width
Loose ). This mandatory requirement simplifies the design of the transmission system between the processor and the memory, and improves the Data Reading speed. For example, a processor that reads and writes memory from a certain 8-fold
To read or write 8 bytes of data at a time, you only need to read or write data of the double type once.
Memory Operation. Otherwise, we may need two memory operations to complete this operation, because the data may be distributed across two 8-byte memory blocks that meet the alignment requirements. Some processors do not meet the requirements for data alignment.
Errors may occur, but Intel's ia32 architecture processor can work correctly regardless of Data Alignment. However, Intel recommends that all programs
Data should be aligned as much as possible. The Microsoft C compiler (cl.exe for 80x86) in win32platform uses the following alignment rules by default:
The alignment modulus of any basic data type T is the size of T, that is, sizeof (t ). For example, for the double type (8 bytes), it is required that the address of the data type is always a multiple of 8, and
Char data (1 byte) can start from any address. GCC in Linux follows another set of rules (not verified in the data, please correct the error): Any 2 bytes
Size (including single-byte ?) The alignment modulus of data types (such as short) is 2, while all other data types (such as long and double) that exceed 2 bytes are 4 as alignment modulus.
  
 
Return to the struct we care about. ANSI
C indicates that the size of a structure type is the sum of the size of all its fields and the size of the padding areas between fields or at the end of the field. Hmm? Fill area? Yes, this is to make the struct field meet the memory alignment requirements and add additional points
Space allocated to the struct. So what are the alignment requirements of the struct itself? Yes, ANSI
The C standard stipulates that the alignment requirements of the struct type cannot be looser than the strictest requirements of all its fields (but this is not mandatory, vc7.1 only makes them as strict ). Let's take a look
Example (the following test environment is Intel celon 2.4g + Win2000 Pro +
Vc7.1, the memory alignment compilation option is "default", that is, the/ZP and/Pack options are not specified ):
  
Typedef struct ms1
{
Char;
Int B;
} Ms1;
  
Assume that ms1 uses the following memory layout (the memory addresses in this article increase from left to right ):
_____________________________
|
| A | B |
|
+ --------------------------- +
Bytes: 1 4
  
 
Because ms1 has the strongest alignment requirement of the B field (INT), so according to the alignment rules of the compiler and ANSI
C Standard, the first address of the ms1 object must be a multiple of 4 (an alignment modulus of the int type. So can the B Field in the above memory layout meet the int type alignment requirements? Well, of course not. If you are
Compiler, how do you cleverly arrange to satisfy the CPU's preferences? Haha, after 1 ms of hard thinking, you must come up with the following solution:
  
_______________________________________
| // |
| A | // padding // | B |
| // |
+ ------------------------------------- +
Bytes: 1 3 4
  
 
This scheme allocates three additional Padding Bytes between A and B, so that when the first address of the entire struct object meets the 4-byte alignment requirement, the B field must also meet the requirements of the int type.
. Therefore, sizeof (ms1) should be 8, and the offset of field B to the first address of the struct is 4. Very understandable, right? Now we need to submit the fields in ms1
In another order:
  
Typedef struct MS2
{
Int;
Char B;
} MS2;
  
Maybe you think MS2 is simpler than ms1, and its layout should be
  
_______________________
|
| A | B |
|
+ --------------------- +
Bytes: 4 1
  
 
Because the MS2 object must also comply with the 4-byte alignment rules, the address of a must be 4-byte alignment because it is equal to the first address of the structure. Well, the analysis is justified, but not comprehensive. Let's come
Consider the problem of defining an MS2 array. The C standard ensures that the space occupied by arrays of any type (including custom structure types) must be equal to the size of a single data of this type.
Multiply by the number of array elements. In other words, there is no gap between the elements of the array. According to the above scheme, the layout of an MS2 array is:
  
| <-Array [1]-> | <-array [2]-> | <-array [3] ......
  
__________________________________________________________
|
| A | B | .............
|
+ ----------------------------------------------------------
Bytes: 4 1 4 1
  
When the first address of the array is 4-byte alignment, array [1]. A is also 4-byte alignment, but what about array [2].? What about array [3].? It can be seen that this scheme does not allow the fields of all elements in the array to meet the alignment requirements when defining the struct array, and must be modified to the following form:
  
___________________________________
| // |
| A | B | // padding // |
| // |
+ --------------------------------- +
Bytes: 4 1 3
  
Now, whether it is to define a separate MS2 variable or MS2 array, all the fields of all elements can meet the alignment requirements. The sizeof (MS2) is still 8, the offset of A is 0, and that of B is 4.
  
Okay. Now you have mastered the basic principles of structured memory layout. Try to analyze a type that is slightly more complex.
  
Typedef struct ms3
{
Char;
Short B;
Double C;
} Ms3;
  
I think you can get the correct layout:
  
Padding
|
_____ V _________________________________
|/| // |
| A |/| B |/padding/| c |
|/| // |
+ ------------------------------------- +
Bytes: 1 1 2 4 8
  
 
The sizeof (short) is equal to 2, and the B field should start with an even address. Therefore, a is followed by a byte, And the sizeof (double) is equal to 8. The C field must be a multiple of 8 addresses.
At the beginning, four bytes are added to the fields A and B.
Bytes, So filling 4 bytes after B can ensure the alignment requirements of the C field. Sizeof (ms3) is equal to 16, B's offset is 2, and C's offset is 8. Next let's look at the characters in the struct.
Segment or structure type:
  
Typedef struct MS4
{
Char;
Ms3 B;
} MS4;
  
In ms3, the most stringent field in memory is C, so the alignment modulus of ms3 data is the same as that of double (8), and field A should be filled with 7 bytes, therefore, the MS4 layout should be:
_______________________________________
| // |
| A | // padding // | B |
| // |
+ ------------------------------------- +
Bytes: 1 7 16
  
Apparently, sizeof (MS4) is equal to 24, and B's offset is equal to 8.
  
 
In actual development, we can change the alignment rules of the compiler by specifying/ZP compilation options. For example, specifying/zpn (N in vc7.1 can be 1, 2, 4, 8, or 16) tells the Compiler
The maximum alignment modulus is N. In this case, the alignment rules of all basic data types smaller than or equal to n Bytes are the same as those of the default one, but the alignment modulus of Data Types greater than n Bytes is limited to n. In fact,
The default alignment option of vc7.1 is equivalent to/zp8. By taking a closer look at msdn's description of this option, we will find that it solemnly warns programmers not to use/zp1 and
/Zp2 option, do not specify/zp4 and/zp8 on a 16-bit platform (think about why ?). Change the alignment options of the compiler and re-analyze the memory layout of the above four types of structs Based on the program running results
It will be a good review.
  
Here, we can answer the last question raised in this article. The memory layout of the struct depends on the requirements of the CPU and operating system.

 

 Original article address
Http://tb.blog.csdn.net/TrackBack.aspx? Postid = 1602970

Related Article

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.