[C ++ primer] Mysterious sizeof (union), sizeof (struct) and memory Alignment Technology

Source: Internet
Author: User

1. Union: C/C ++ keywords (union)

The Declaration of the shared body and the definition and structure of the shared body variables are very similar. Format:

 

Union shared body name {data type member name;...} variable name;

The shared body indicates that several variables share the same memory location, saving different data types and variables of different lengths at different times. in union, all the common body members share one space and can only store the value of one of the member variables at a time. When a shared body is declared, the compiler automatically generates a variable whose length is an integer multiple of the maximum variable length in the Union (pay attention to the array)

Example 1:

 

Union Foo {

Int I;

Char C;

Double K;

};

Sizeof (FOO); // double occupies a maximum of 8 bytes, so the size of Union foo is 8 bytes.

 

Example 2:

Union a {int A [5]; // 20 short B; // 2 double C; // 8 char P2; // 1}; struct B {int N; // 4 bytes a; // 24 bytes char C [10]; // 10 bytes };

 

 

Sizeof (a); // 24 instead of 20 ???

Sizeof (B); // 48 instead ???

Alignment: When memory is allocated, each member is placed in a multiple-length position. If not, the complement alignment is aligned.

Completion: the total length of the space required for the entire structure variable must be a multiple of the longest members. If the total length is not enough, whether it is alignment or population, the maximum length of the member is more than 4, which is counted as 4.

 

A actually occupies 20 bytes of memory, but it must be an integer multiple of the double variable of 8 bytes, so the alignment is 24;

Because a actually occupies 24 bytes, B actually occupies 38 bytes, but a is 8 bytes aligned, so int N and char C [10] also need 8 bytes aligned, A total of 8 + 24 + 16 = 48 bytes.

Example 3:

 

union f   {   char s[10];   int i;   };

Sizeof (f); // 12
Explanation: in this Union, foo's memory space is 12, three times that of the int type, not 10 in length.
If the int type is changed to double, the memory space of foo is 16, which is twice that of double type.

2. struct

For details, see the memory alignment example.

 

3. Memory alignment

1) concept: "memory alignment" should be the "jurisdiction" of the compiler ". The compiler arranges each "data unit" in the program at an appropriate position.

2) cause:

1. Platform reason (reason for transplantation): Not all hardware platforms can access any data on any address. Some hardware platforms can only retrieve certain types of data at some addresses, otherwise, a hardware exception is thrown.

2. Performance reasons: Data Structures (especially stacks) should be aligned on natural boundaries as much as possible. The reason is: to access non-alignment memory, the processor needs to perform two memory accesses, while alignment memory access only needs one access.

3) alignment rules

Each compiler on a specific platform has its own default "alignment coefficient" (also called alignment modulus ). Programmers can use the pre-compiled command # pragma pack (N), n =, and 16 to change this coefficient. n is the alignment coefficient you want to specify ".

Rules:

1. Data member alignment rules: the data member of the structure (struct) (or union). The first data member is placed at the position where the offset is 0, in the future, the alignment of each data member is performed according to the value specified by # pragma pack and the smaller value of the data member's length.

2. Overall alignment rules of the structure (or union): After the data members align themselves, the structure (or union) itself also needs to be aligned, alignment is performed according to the value specified by # pragma pack and the smaller value in the maximum data member length of the structure (or union.

3. Combined with values 1 and 2, we can infer that when the n value of # pragma pack is equal to or exceeds the length of all data members, the N value will not have any effect.

 

Pragma pack (1)

 

1> data member alignment:

# Pragma pack (1) struct test_t {int A;/* int type, 4> 1 aligned by 1; Start offset = 0 0% 1 = 0; storage location range [4%] */Char B;/* char type, length 1 = 1 aligned by 1; Start offset = 4 1 = 0; storage location range [4] */short C;/* short type, length 2> 1 aligned by 1; Start offset = 5 5% 1 = 0; storage location range [5, 6] */Char d [6];/* char type, 1 = 1 aligned by 1; Start offset = 7 7% 1 = 0; storage location range [7, C] */};/* char d [6] should be regarded as 6 char variables */

Sizeof (test_t); // The output is 13

2> overall alignment

Overall alignment coefficient = min (max (INT, short, char), 1) = 1

Overall size (size) = $ (total member size) by $ (overall alignment coefficient) rounded = 13/* 13% 1 = 0 */

 

Pragma pack (2)

1> Member Data Alignment

  

# Pragma pack (2) struct test_t {int A;/* int type, length 4> 2 aligned by 2; Start offset = 0 0% 2 = 0; storage location range [4%] */Char B;/* char type, length 1 <2 aligned by 1; Start offset = 4 1 = 0; storage location range [4] */short C;/* short type, length 2 = 2 aligned by 2; Start offset = 6 6% 2 = 0; storage location range [6, 7] */Char d [6];/* char type, 1 <2 aligned by 1; Start offset = 8 8% 1 = 0; storage location range [8, d] */};

Total member size = 14

2> overall alignment

Overall alignment coefficient = min (max (INT, short, char), 2) = 2

Overall size (size) = $ (total member size) by $ (overall alignment coefficient) rounded = 14/* 14% 2 = 0 */

 

Iv. ultimate example

 

Example 1:

union A{int t;   //4short m; //2char p;  //1};struct B  {    A a;          //4    double c;    //8    char p2;     //1};

Sizeof (B); // 24

B adopts the 8-byte alignment of double length, so a is changed to 8 bytes within B. The actual usage of B is 8 + 8 + 1 = 17. Then it is filled with an integer multiple of 8 and the last 24 bytes.

 

Abnormal Example 2:

struct B  {    union A{int t;   //4short m; //2char p;  //1} ;    double c;    //8char p2;     //1};

 

Sizeof (B); // 16

 

If your first reaction was 24, you would have been lying down and shot. Think about why !!

4 + 8 + 1 = 13 The minimum multiples of the maximum type of 8 is 16

Attachment: Sample Code in GCC

# Include "stdio. H "typedef struct BB {Union AA // No typedef {int t; // 4 short m; // 2 char P; // 1} AA; double C; // 8 char P2; // 1} BB; typedef union a // typedef {int t; // 4 short m; // 2 char P; // 1} A; typedef struct B {A; // 4 double C; // 8 char P2; // 1} B; int main () {printf ("BB: % d \ n", sizeof (bb); printf ("B: % d \ n", sizeof (B); Return 0 ;}

 

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.