Here is a simple code that displays a number equal to 3, why? where did these 3 bytes come from

struct student { char name[20]; char sex; int age; float mark; }; struct student s2; int main( void ) { printf("%d", sizeof(s2) - sizeof(s2.sex) - sizeof(s2.age) - sizeof(s2.mark) -sizeof(s2.name)); // = 3 } 

and one more question of the same topic

  union rec { int a[5]; struct student st; } r; int main( void ) { printf("%d", sizeof(r) == sizeof(student) ); } 

why returns true, if in fact no truth is, 5 * 4 bytes of difference

  • 3
    Obviously, after char sex, 3 bytes are added so that the offset of the next int is a multiple of 4. Optimization, simply put. In theory, if char sex is moved to the end, then the size of the structure will correspond to the calculated one, but if you create an array of such structures, the beginning of each of the structures will most likely be aligned to a multiple of 4, i.e. the same +3 bytes. - insolor
  • @Eugene536 such things should be in the compiler description with the means how to change this behavior. - alexlz

1 answer 1

These three additional bytes are the result of the so-called alignment. Its essence lies in the fact that the data is placed in the memory is not always "close", after each other, but by addresses that are multiples of the field size. For example, if an int on a given platform has a size of 4 bytes, then a field of this type will be placed not immediately after the previous field, but at the nearest address multiple of four. All these tweaks with alignment serve the same purpose - to increase the speed of work, since it is easier for the processor to access data at the "aligned" addresses. By the way, if your structure consisted of only one-byte fields, then this effect, for obvious reasons, would not be

Regarding the second part of the question, it is also quite explicable - this follows from the very essence of the union, which, unlike structures, stores data in the same memory area, and its size is the size of its maximum field. The maximum size is st, therefore sizeof (r) is equal to sizeof (student)

On the first part of the question, read here and here , on the second part - for example, here

By the way:

AAA, I can not understand where these 20 bytes will lie ???)))

Here is a simple analogy for you - imagine a switch with which you turn on / off the light. Instead of one switch, you could use two different switches. One to turn on and the other to turn off the light. But it is more convenient to have it all in one switch. That is, when the light is on, you cannot turn it on again, when it is turned off - you cannot turn it off again. union is something similar - when you use one of its fields, you cannot use another (or rather you can, but it does not make sense and will lead to errors). The analogy, of course, is crooked, but maybe it will be easier for you to understand this.

  • the lectures were also written, but where is the memory for the array in the union? before that, I can't do it at all, how is it in one area ..? they cannot fit into one area, 20 bytes is not enough for an array - Eugene536
  • union rec {int a [5]; struct student st; } r; Well, in this union there is a structure and an array of 5 numbers, I realized that memory is allocated only for st (since the size is larger), but how will it allocate memory for the array? - Eugene536
  • one
    > they cannot fit in one area, 20 bytes is not enough for an array, so there will not be 20 of them. I will repeat once more - sizeof (r) will be equal to the size of the maximum field of your union. The maximum size in it is st of the student type, the size of which is 32 bytes (or how much it will occupy on your platform). - DreamChild
  • one
    Under the array, it will use the same memory as under st - this is the meaning of union and its main difference from struct is that the data inside the union “overlaps” each other, being stored in the same memory. If you write something to st, you will erase what was in a - DreamChild
  • one
    they will lie in the same place. Just recording one field, you will "overwrite" another. This may make sense in the case of strict memory savings, but such cases are very rare, and even if necessary, the union must be used very carefully. Try to guess for yourself what can happen if you carelessly handle memory, which is common to all fields - DreamChild