Why is the addition padded if char comes after int?

For example, there is a structure

struct A { char a; int i; }; 

In this case, we have [1 byte] + pad [3 bytes] + int [4 bytes] = 8.

Now let's make a small update in the structure above,

 struct A { int i; char a; }; 

In this case, char comes after int and there is no need to add padding bytes, this means sizeof (A) = 5 bytes, but in this case I also get an 8-byte result. Why?

Ok and what about this case

 struct s { int b; double c; char a; }; 

According to the logic below, there is: size = b[4 bytes] + padding[4 bytes] + c[8] + a[1] + padding[7 bytes to align with double] = 24 , but after execution I get 16 How is this possible?

+5
source share
4 answers

In this case, char appears after int and there is no need to add padding bytes, this means sizeof(A) = 5 bytes, but in this case I also get the result of byte 8 . What for?

First you need to understand why you need to fill out?
Wiki says that:

Aligning the data structure is a way of organizing and accessing data in the computer's memory. It consists of two separate but related problems: data alignment and the addition of a data structure. When a modern computer reads or writes to a memory address, it will do it in chunks of word size (for example, 4 byte blocks in a 32-bit system) or more. Data alignment means transferring data with a memory offset of several multiple word sizes, which increases system performance due to the way the processor processes the memory . To align the data, you may need to insert some meaningless bytes between the end of the last data structure and the beginning of the next, which is filling in the data structure.

To make the size a multiple of 4 (alignment int ), the second fragment will be padded with bytes 3 . After compilation, the second fragment will be supplemented for proper alignment as

 struct A { int i; char a; char Padding[3]; // 3 bytes to make total size of the structure 8 bytes }; 

EDIT: Always remember the two golden rules for filling out a structure:

  • Filling is only introduced when a member of the structure is followed by a member requiring more alignment or at the end of the structure.
  • The last element is filled with the number of bytes required, so the total size of the structure must be a multiple of the largest alignment of any element in the structure.

When

 struct s { int b; double c; char a; }; 

alignment will be performed as

 struct s { int b; // 4 bytes. b is followed by a member with larger alignment. char Padding1[4]; // 4 bytes of padding is needed double c; // 8 bytes char d; // 1 byte. Last member of struct. char Padding2[7]; // 7 bytes to make total size of the structure 24 bytes }; 

Also note that by changing the order of the elements in the structure, you can change the number of indentation necessary to maintain alignment. This can be done if members are sorted in descending order of alignment requirements.

 struct s { double c; // 8 bytes int b; // 4 bytes char a; // 1 byte. Only last member will be padded to give structure of size 16 }; 
+6
source

The reason the compiler needs to add an add-on at the end of your structure is because the structure can be part of an array, and each element of the array must be properly aligned.

It seems your platform wants the int to be aligned with 4 bytes.

If you declare an array of your struct A :

 struct A array[2]; 

Then the first member of int array[1] should also have alignment of 4 bytes. Thus, the compiler loads your struct A at 8 bytes to accomplish this, while if it hadn't added any additions and sizeof(struct A) was 5 bytes, array[1] would not be aligned correctly.

(Keep in mind that the compiler cannot insert padding between the elements of the array, the filling should be part of the array elements themselves, since the sizeof array should be the same as sizeof(struct A) * 2 in the above case)

+1
source

Not only each struct element must be data bound, but the struct itself must be aligned to fit the largest member in the struct . Thus, the addition is added to struct A , so its size must be a multiple of sizeof i and sizeof a .

Take a look at the C FAQ here

0
source

If you have an array of structures, all elements in the array should have the same size and alignment; this would mean that for things in the array, the size should be a multiple of alignment. The only time it would be useful to have a structure whose size was not a multiple of alignment would be if it were not included directly in another array, but used instead as part of another structure. Such a situation sometimes arises, but not often enough to deserve special attention in the design of the language.

0
source

Source: https://habr.com/ru/post/1214934/


All Articles