Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the size of this union larger than expected?

Tags:

c

When I type in the following code, I get a result of 32 bytes. It supposed to be 28 bytes, though. Why do I get that result?

//size of union variable

union U {
    int x[7];
    double y[3];
}z;

int main(){
    printf("%d",sizeof(z));
    return 0;
}
like image 715
Ashikur Rahman Avatar asked Aug 28 '19 12:08

Ashikur Rahman


People also ask

Why is the size of a union greater than its members?

The alignment of your union must be the largest alignment of any of its members. This is 4. Therefore, the size of the union must be aligned to that size. It could have been 5 (as c is the largest member of the union), but because the alignment of the union as a whole is 4, the size of the union is padded to 8.

What determines the size of a union in C?

When we declare a union, memory allocated for a union variable of the type is equal to memory needed for the largest member of it, and all members share this same memory space. In above example, "char arr[8]" is the largest member. Therefore size of union test is 8 bytes.

What is the union size?

The size of a union is sufficient to contain the largest of its data members. Each data member is allocated as if it were the sole member of a struct. That means each member share the same memory region. There is at most one member active, but you can't find out which one.


2 Answers

Unions, like structs, are padded to agree with the required alignment of their members.

double is aligned on a multiple of eight on your platform, and 32 is the smallest multiple of eight that is at least 28.

like image 199
molbdnilo Avatar answered Oct 25 '22 13:10

molbdnilo


As explained in another answer, padding is used to facilitate struct (and union) member alignment and is the reason for the unexpected size that you see.

To see the size you expected (i.e. without padding), you can force the code to to ignore the alignment issue by using a pragma statement. #pragma pack specifically is used to indicate to the compiler that the struct/union be packed in a specific way, by changing the addressing alignment from the default value to something else.

The following results in a size of 28:

#pragma pack(1) //Sets compiler to align on 1 byte address boundaries
                //(Effectively removing all padding)

union U {
    int x[7];
    double y[3];
}z;

#pragma pack() //Set packing back to what it was before

int main(){
    printf("%d",sizeof(z));
    return 0;
}
like image 31
ryyker Avatar answered Oct 25 '22 12:10

ryyker