Structure bytes alignment in C language memory

Source: Internet
Author: User

I. effect and reason of byte alignment:
Alignment functions and causes: the processing of storage space varies greatly by hardware platform. Some platforms can only access certain types of data from some specific addresses. For example, some architectures may encounter errors when the CPU accesses a variable that is not aligned, so in this architecture, the programming must ensure the byte alignment, and other platforms may not, however, if the data storage is not aligned according to the appropriate platform requirements, the access efficiency will be compromised. For example, some platforms start from the even address each time they read data. If an int type (assuming a 32-bit System) is stored at the beginning of the even address, the 32bit can be read in a read cycle, if the data is stored at the beginning of the odd address, two read cycles are required, and the high and low bytes of the two read results are pieced together to obtain the 32bit data, obviously, reading efficiency is greatly reduced.
Ii. byte alignment rules:
Four important concepts:
1. alignment value of the Data Type itself: For char-type data, its alignment value is 1, for short-type data is 2, for int, float, double type, its own alignment value is 4 bytes.
2. The alignment value of a struct or class: The value with the largest alignment value among its members.
3. Specify the alignment value: # The alignment value specified when pragma pack (value) is used.
4. Valid alignment values of data members, struct, and classes: the alignment value of the data itself and the value smaller than the specified alignment value.
Supplement:
1). Each member is aligned in its own way, and the length can be minimized.
2). The default alignment of complex types (such as structures) is the alignment of its longest member, so that the length can be minimized when the member is a complex type.
3) The alignment length must be an integer multiple of the largest alignment parameter in the member, so that each item can be aligned at the boundary when processing the array.

# Pragma pack (1)
Struct test
{
Static int a; // static var
Double m4;
Char m1;
Int m3;
}
# Pragma pack ()
// Sizeof (test) = 13;
 
Class test1 {};
// Sizeof (test1) = 1;
 
/* Note:
1. Static members in the structure or class do not affect the structure or class size, because the storage location of static variables is irrelevant to the instance address of the structure or class;
2. the structure or class size without member variables is 1, because each instance of the structure or class must have a unique address in the memory. */

# Pragma pack (1)
Struct test
{
Static int a; // static var
Double m4;
Char m1;
Int m3;
}
# Pragma pack ()
// Sizeof (test) = 13;
 
Class test1 {};
// Sizeof (test1) = 1;
 
/* Note:
1. Static members in the structure or class do not affect the structure or class size, because the storage location of static variables is irrelevant to the instance address of the structure or class;
2. the structure or class size without member variables is 1, because each instance of the structure or class must have a unique address in the memory. */
Example:

// Analyze the following example C:
//
# Pragma pack (2)/* specify to align by 2 bytes */
Struct C
{
Char B;
Int;
Short c;
};
# Pragma pack () // restore alignment
/*
The first variable B's own alignment value is 1 and the specified alignment value is 2. Therefore, the valid alignment value of B is 1. Suppose C starts from 0x0000, then B is stored in 0x0000, 0 x 0000% 1 = 0;
In the second variable, the alignment value is 4 and the alignment value is 2. Therefore, the valid alignment value is 2, therefore, the data is stored in four consecutive bytes, namely 0x0002, 0x0003, 0x0004, and 0 x 0002%.
The alignment value of the third variable c is 2, so the valid alignment value is 2. The order is 0x0006, 0 x 0006% 2 = 0.
Therefore, the variable struct C is stored in a total of eight characters from 0x0000 to 0x0007. And struct C's own alignment value is 4, so the valid alignment value of struct C is 2.
Again 8% 2 = 0, struct C only occupies eight bytes from 0x0000 to 0x0007. So sizeof (struct C) = 8.
If you change # pragma pack (2) to # pragma pack (4), the size of the structure is 12.
*/



// Let's look at the example below.
//
# Pragma pack (8)
Struct S1
{
Char;
Long B;
};
Struct S2 {
Char c;
Struct S1 d;
Long e;
};
# Pragma pack ()
 
The sizeof (S2) result is 24.
/*
S1:
Member a is 1-byte aligned by 1 byte by default, and the specified alignment parameter is 8. Among the two values, 1 and a are aligned by 1 byte;
The member B is 4 bytes. The default value is 4 bytes aligned. Then it is 4 bytes aligned, so the sizeof (S1) should be 8;
 
S2:
C is the same as a in S1, which is aligned by 1 byte,
D is a structure. It is 8 bytes. What is its alignment? For the structure, its default alignment is the largest alignment parameter used by all its members, and S1 is 4. Therefore, member d is aligned by 4 bytes.
The member e is 8 bytes, which is aligned by 8 bytes by default. It is the same as the specified one, so it is connected to the boundary of 8 bytes. At this time, 12 bytes are used, therefore, four bytes are added, and member e is placed starting from 16th bytes;
The length is 24 and can be divisible by 8 (member e is aligned by 8 bytes). A total of 24 bytes are used.
A B
Memory layout of S1: 11 **, 1111,
C S1.a S1. B d
Memory layout of S2: 1 ***, 11 ***, 1111, *** 11111111
*/


// Let's look at the example below.
//
# Pragma pack (8)
Struct S1
{
Char;
Long B;
};
Struct S2 {
Char c;
Struct S1 d;
Long e;
};
# Pragma pack ()
 
The sizeof (S2) result is 24.
/*
S1:
Member a is 1-byte aligned by 1 byte by default, and the specified alignment parameter is 8. Among the two values, 1 and a are aligned by 1 byte;
The member B is 4 bytes. The default value is 4 bytes aligned. Then it is 4 bytes aligned, so the sizeof (S1) should be 8;
 
S2:
C is the same as a in S1, which is aligned by 1 byte,
D is a structure. It is 8 bytes. What is its alignment? For the structure, its default alignment is the largest alignment parameter used by all its members, and S1 is 4. Therefore, member d is aligned by 4 bytes.
The member e is 8 bytes, which is aligned by 8 bytes by default. It is the same as the specified one, so it is connected to the boundary of 8 bytes. At this time, 12 bytes are used, therefore, four bytes are added, and member e is placed starting from 16th bytes;
The length is 24 and can be divisible by 8 (member e is aligned by 8 bytes). A total of 24 bytes are used.
A B
Memory layout of S1: 11 **, 1111,
C S1.a S1. B d
Memory layout of S2: 1 ***, 11 ***, 1111, *** 11111111
*/

Iii. How should we consider byte alignment in programming?
If we want to save space during programming, we only need to assume that the first address of the structure is 0, and then sort the variables according to the above principles, the basic principle is to declare the variables in the structure according to the type size from small to large, and minimize the space to fill. Another way is to take the space for the efficiency of time, we show to fill the space for alignment, for example, there is a way to use the space for time is to explicitly insert reserved members:
Struct
{
Char;
Char reserved [3]; // use space for time
Int B;
};
The reserved member has no significance for our program. It just fills the space to achieve byte alignment. Of course, even if this member is not added, the compiler will automatically fill the alignment for us, we add it as a reminder.
Iv. potential risks of byte alignment
Many of the potential alignment risks in the Code are implicit. For example, in forced type conversion. For example:
Unsigned int I = 0x12345678;
Unsigned char * p = NULL;
Unsigned short * p1 = NULL;
P = & I;
* P = 0x00;
P1 = (unsigned short *) (p + 1 );
* P1 = 0x0000;
The last two lines of code access the unsigned short variable from the odd boundary, which obviously does not comply with the alignment rules. On X86, similar operations only affect the efficiency, but on MIPS or iSCSI, they may be an error because they require the bytes to be aligned.
5. How to find problems with byte alignment
If alignment or assignment occurs, first check
1. Alignment value set by the compiler
2. Check whether the system supports non-alignment access.
3. If alignment or alignment is supported, some special modifications are required to mark special access operations.

From focusing on Embedded Systems

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.