+ 7

Size confusion in structure and Union

https://code.sololearn.com/c5APFsKlBoiY/?ref=app In my code i am getting the output 20 24 48 but I think the output should be:- 19 for the struct inside the union 19 again the same because Union reserves memory for the largest variable. 43 and the outside Struct is 43 because 19+20+4=43

31st Oct 2019, 12:37 PM
Robin Singh
Robin Singh - avatar
14 Respostas
+ 11
this ie caused by structure alignment which the compiler automatically did for you, let me check a tutorial made by Babak for you https://www.sololearn.com/post/78037/?ref=app
31st Oct 2019, 1:04 PM
✳AsterisK✳
✳AsterisK✳ - avatar
+ 11
Robin Singh this little code snippet explains bit from it. #HappyCoding https://code.sololearn.com/cH03YBD5Yb6r/?ref=app
1st Nov 2019, 8:42 PM
BlackRose Mike
BlackRose Mike - avatar
+ 9
Babak Thanks!!! Yes, now it makes total sense. I was playing with this _Alignof operator and I noticed that: if there is a member of double type in struct or union then the alignment is 8, and if I remove double from struct or union, then alignment is 4. So, the compiler is responsible for these optimizations, right.. https://code.sololearn.com/c7UuJ0sRiHI2/?ref=app
31st Oct 2019, 6:56 PM
voja
voja - avatar
+ 7
" I still don't get why is the size of union y equal to 24?" As you may know, the union's members overlap each other and only one of its members is available at a time. Intuitively (without referring to fancy standard), The required space/size of a union in order to guarantee that its largest member (in this example the structure inside the union) can be appropriately stored in the shared area of the union's memory, the compiler rightly takes up 24 bytes ( with natural alignment ) of memory to be able to handle both the double type (8 bytes) and user-defined structure with larger size.
31st Oct 2019, 4:54 PM
Babak
Babak - avatar
+ 6
voja I should've mentioned it, you're right. It's all about the maximum alignment of the union. If you make a query like printf ("%zu", _Alignof(z.y)); Then you'll see that it's set to 8, which means in order to allocate the required space for the structure, it must be as large as 8*3 = 24 because 8*2 = 16 can't hold 20 bytes.
31st Oct 2019, 6:13 PM
Babak
Babak - avatar
+ 5
Babak but the structure takes up 20 bytes, so there's enough memory for double variable c, which takes 8 bytes, there's no need to add 4 bytes more. Union reserves memory for the largest member (in this case its struct, 20 bytes) and as you already mentioned union members overlap each other. I just don't get why do we need those extra 4bytes.
31st Oct 2019, 5:49 PM
voja
voja - avatar
+ 4
voja Choosing required alignment is a definitive decision that is made by compiler indicating the number of bytes between successive addresses at which a given object can be allocated. Also (fundamental) alignment, which is an integer number imposed by implementation (as you've seen), has an upper limit equal to the largest alignment support by the compiler and can be found out as printf( "\n%zu", _Alignof(max_align_t) ); // 16 This is usually equal to the largest scalar type, which is long double, printf( "\n%zu", _Alignof(long double) ); // 16 The larger the alignment, the stricter it becomes. If the structure inside union had a alignment of 16 for example, then the alignment of the whole block would've been greater and the additional padding should've been inserted between each member. _____ max_align_t type has defined in <stddef.h>
1st Nov 2019, 3:44 AM
Babak
Babak - avatar
+ 4
Please consider that the wrong conversion specifier and length modifier in printf statements causes undefined behavior according to the standard, " If a length modifier appears with any conversion specifier other than as specified above, the behavior is undefined. [...] If a conversion specification is invalid, the behavior is undefined. " Here is a quick reference for making sure that yours complies. https://code.sololearn.com/WWEzbX1TS0m2/?ref=app
2nd Nov 2019, 5:21 AM
Babak
Babak - avatar
+ 2
voja "and I noticed that: if there is a member of double type in struct or union then the alignment is 8, and if I remove double from struct or union, then alignment is 4. " Very nice! 👍 Just change "double" to "float", then it will make the difference. I think this should be the final answer.
1st Nov 2019, 12:36 AM
o.gak
o.gak - avatar
+ 1
There are concepts like structure member alignment, padding and data packing, because of which the size varies.
31st Oct 2019, 1:33 PM
Avinesh
Avinesh - avatar
+ 1
✳AsterisK✳ Hey Mr *ptr thanks I read this now I now that size of union and structure is determined by the compiler
31st Oct 2019, 1:33 PM
Robin Singh
Robin Singh - avatar
+ 1
I still don't get why is the size of union y equal to 24?
31st Oct 2019, 3:34 PM
voja
voja - avatar
+ 1
Also, you can pack your structure members by adding : #pragma pack(1) in your code. Then you'll get the output you firstly expected (19,19,43)
31st Oct 2019, 3:41 PM
voja
voja - avatar
+ 1
See a processor will have processing word length as that of data bus size. So on a 32 bit machine the word size will be 4 bytes. Also the memory is byte addressable and arranged sequentially. Now in one memory cycle the processor can fetch 4 bytes. So the first output is 20 because 1 padding byte is added to the char data type so that fetching can be in multiples of 4. If you get this then the rest is understandable.
31st Oct 2019, 6:10 PM
Avinesh
Avinesh - avatar