This blog (http://blog.csdn.net/livelylittlefish) posted the author (321, small fish) related research, learning content made notes, welcome friends to correct me!
byte alignment
1. Basic Concepts
BYTE alignment: The computer storage system stores data in byte, with different data types occupying different spaces, such as Integer (int) data accounting for 4 bytes, character type (char) data in one byte, short integer data two bytes, and so on. In order to read and write data at high speed, the data is stored at the beginning of an address by default, such as Integer data (int), which is stored by default at the starting position where the address can be divisible by 4, and character data (char) can be stored at any address location (divisible by 1). Short data stores the starting position where the address can be divisible by 2. This is the default byte alignment.
2. Illustrative examples
It is obvious that the default alignment can waste very much space, such as the following structure:
struct student
{
Char name[5];
int num;
Short score;
}
Originally used only 11bytes (5+4+2) space, but because the int type default 4 byte alignment, stored in the address can be divisible by 4 of the starting position, that is: Suppose Name[5] from 0 to store, it accounted for 5bytes, and Num is from the 8th (offset) bytes start to store. So sizeof (student) = 16. So the middle empty a few bytes idle. But it is convenient for the computer to read and write data at high speed, which is a way of exchanging space for time. Its data is aligned for example with the following:
|char|char|char|char|
|char|----|----|----|
|--------int--------|
|--short--|----|----|
Let's say we change the order of the variables in the struct to:
struct student
{
int num;
Char name[5];
Short score;
}
Then num is stored from 0, and name starts from the 4th (offset) Byte, 5 bytes in a row, score from the 10th (offset), so sizeof (student) = 12. Its data is aligned for example with the following:
|--------int--------|
|char|char|char|char|
|char|----|--short--|
Let's say we change the order of the variables in the struct again to:
struct student
{
int num;
Short score;
Char name[5];
}
Then, sizeof (student) = 12. Its data is aligned for example with the following:
|--------int--------|
|--short--|char|char|
|char|char|char|----|
Verify the code such as the following:
#include <stdio.h>typedef Struct{char name[5];int num;short score;} Student1;typedef struct{int Num;char name[5];short score;} Student2;typedef struct{int num;short Score;char name[5];} Student3;int Main () {student1 s1={"Tom", 1001,90};student2 s2={1002, "Mike", 91};student3 s3={1003,92, "Jack"};p rintf (" Student1 size =%d/n ", sizeof (S1));p rintf (" Student2 size =%d/n ", sizeof (S2));p rintf (" student3 size =%d/n ", sizeof (S3)); printf ("/nstudent1 address:0x%08x/n", &s1);p rintf ("Name address:0x%08x/n", S1.name);p rintf ("Num address:0 x%08x/n ", &s1.num);p rintf (" Score address:0x%08x/n ", &s1.score);p rintf ("/nstudent2 address:0x%08x/n ",& S2);p rintf ("num address:0x%08x/n", &s2.num);p rintf ("Name address:0x%08x/n", S2.name);p rintf ("Score Addre ss:0x%08x/n ", &s2.score);p rintf ("/nstudent3 address:0x%08x/n ", &S3);p rintf (" num address:0x%08x/n ", &S3 . Num);p rintf ("Score address:0x%08x/n", &s3.score);p rintf ("Name address:0x%08x/n",s3.name); return 0;}
The results of the execution are as follows:
student1 size = 16student2 size = 12student3 size = 12student1 address:0x0013ff70 name address:0x0013ff70 num ADDRESS:0X0013FF78 score address:0x0013ff7cstudent2 address:0x0013ff64 num address:0x0013ff64 name add RESS:0X0013FF68 score Address:0x0013ff6estudent3 address:0x0013ff58 num address:0x0013ff58 score Address: 0x0013ff5c name address:0x0013ff5e
3. #pragma pack () command
To save space, we were able to specify the alignment of the program with the #pragma pack () command at encoding, the number of bytes aligned in parentheses, and the default alignment if the contents of the command brackets were empty. For example, for the first struct above, let's say that you manually set the number of aligned bytes by this command, such as the following:
#pragma pack (2)//Set 2-byte alignment
struct strdent
{
Char name[5]; itself 1-byte aligned, smaller than 2-byte alignment, aligned by 1 bytes
int num; itself 4-byte aligned, larger than 2-byte alignment, aligned by 2 bytes
Short score; itself is also 2-byte aligned and still aligned by 2 bytes
}
#pragma pack ()//de-set byte alignment
Then, num is stored from the 6th (offset) byte and score from the 10th (offset) byte, so sizeof (student) = 12, whose data is aligned for example by:
|char|char|
|char|char|
|char|-----|
|----INT----|
|----INT----|
|--short---|
This changes the default byte alignment to make more use of the storage space, but it reduces the speed at which the computer reads and writes data, and is a way of exchanging time for space.
Verify the code such as the following:
#include <stdio.h> #pragma pack (2) typedef struct{char NAME[5];INT Num;short score;} Student1;typedef struct{int Num;char name[5];short score;} Student2;typedef struct{int num;short Score;char name[5];} Student3; #pragma pack () int main () {student1 s1={"Tom", 1001,90};student2 s2={1002, "Mike", 91};student3 s3={1003,92, " Jack "};p rintf (" student1 size =%d/n ", sizeof (S1));p rintf (" Student2 size =%d/n ", sizeof (S2));p rintf (" student3 size =%d/n , sizeof (S3));p rintf ("/nstudent1 address:0x%08x/n", &s1);p rintf ("Name address:0x%08x/n", S1.name);p rintf ("num address:0x%08x/n ", &s1.num);p rintf (" Score address:0x%08x/n ", &s1.score);p rintf ("/nstudent2 address:0x%08 x/n ", &s2);p rintf (" num address:0x%08x/n ", &s2.num);p rintf (" Name address:0x%08x/n ", S2.name);p rintf (" s Core address:0x%08x/n ", &s2.score);p rintf ("/nstudent3 address:0x%08x/n ", &S3);p rintf (" Num address:0x%08x/ n ", &s3.num);p rintf (" Score address:0x%08x/n ", &s3.score);p rintf (" Name address:0x%08x/n ", S3.name); return 0;}
The results of the execution are as follows:
student1 size = 12student2 size = 12student3 size = 12student1 address:0x0013ff74 name address:0x0013ff74 num ADDRESS:0X0013FF7A score address:0x0013ff7estudent2 address:0x0013ff68 num address:0x0013ff68 name add RESS:0X0013FF6C score Address:0x0013ff72student3 address:0x0013ff5c num ADDRESS:0X0013FF5C score Address: 0x0013ff60 name address:0x0013ff62
If this is #pragma pack (1), the result of the execution is as follows:
student1 size = 11student2 size = 11student3 size = 11student1 address:0x0013ff74 name address:0x0013ff74 num ADDRESS:0X0013FF79 score address:0x0013ff7dstudent2 address:0x0013ff68 num address:0x0013ff68 name add RESS:0X0013FF6C score Address:0x0013ff71student3 address:0x0013ff5c num ADDRESS:0X0013FF5C score Address: 0x0013ff60 name address:0x0013ff62
4. Examples
Programs such as the following:
#include <stdio.h>class a1{public:int a;static int b; A1 (); ~a1 ();}; Class A2{public:int A;char C; A2 (); ~a2 ();}; Class A3{public:float A;char C; A3 (); ~a3 ();}; Class A4{public:float a;int B;char C; A4 (); ~a4 ();}; Class a5{public:double d;float a;int B;char C; A5 (); ~a5 ();}; Main () {printf ("A1 size =%d/n", sizeof (A1));p rintf ("A2 size =%d/n", sizeof (A2));p rintf ("A3 size =%d/n", sizeof (A3)); printf ("A4 size =%d/n", sizeof (A4));p rintf ("A5 size =%d/n", sizeof (A5));}
The sample takes the default alignment and executes the result such as the following:
A1 size = 4A2 size = 8a3 size = 8a4 size = 12a5 size =
Description: Static variables are stored in the global data area, and sizeof calculates the size of the allocated space in the stack, so it is not counted.
If the #pragma pack (2) command is added, the result of the execution is as follows:
A1 size = 4A2 size = 6a3 size = 6a4 size = 10a5 size =
byte alignment in C + +