Difference between a Structure and a Union
Asked Answered
D

17

467

Is there any good example to give the difference between a struct and a union? Basically I know that struct uses all the memory of its member and union uses the largest members memory space. Is there any other OS level difference?

Deeprooted answered 6/12, 2008 at 17:56 Comment(0)
G
752

With a union, you're only supposed to use one of the elements, because they're all stored at the same spot. This makes it useful when you want to store something that could be one of several types. A struct, on the other hand, has a separate memory location for each of its elements and they all can be used at once.

To give a concrete example of their use, I was working on a Scheme interpreter a little while ago and I was essentially overlaying the Scheme data types onto the C data types. This involved storing in a struct an enum indicating the type of value and a union to store that value.

union foo {
  int a;   // can't use both a and b at once
  char b;
} foo;

struct bar {
  int a;   // can use both a and b simultaneously
  char b;
} bar;

union foo x;
x.a = 3; // OK
x.b = 'c'; // NO! this affects the value of x.a!

struct bar y;
y.a = 3; // OK
y.b = 'c'; // OK

edit: If you're wondering what setting x.b to 'c' changes the value of x.a to, technically speaking it's undefined. On most modern machines a char is 1 byte and an int is 4 bytes, so giving x.b the value 'c' also gives the first byte of x.a that same value:

union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

prints

99, 99

Why are the two values the same? Because the last 3 bytes of the int 3 are all zero, so it's also read as 99. If we put in a larger number for x.a, you'll see that this is not always the case:

union foo x;
x.a = 387439;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

prints

387427, 99

To get a closer look at the actual memory values, let's set and print out the values in hex:

union foo x;
x.a = 0xDEADBEEF;
x.b = 0x22;
printf("%x, %x\n", x.a, x.b);

prints

deadbe22, 22

You can clearly see where the 0x22 overwrote the 0xEF.

BUT

In C, the order of bytes in an int are not defined. This program overwrote the 0xEF with 0x22 on my Mac, but there are other platforms where it would overwrite the 0xDE instead because the order of the bytes that make up the int were reversed. Therefore, when writing a program, you should never rely on the behavior of overwriting specific data in a union because it's not portable.

For more reading on the ordering of bytes, check out endianness.

Graniteware answered 6/12, 2008 at 17:59 Comment(11)
using this example, in union, if x.b='c' what gets stored in x.a? is it the reference # of the char?Noranorah
hopefully that explains in more detail what's stored in x.a when you set x.b.Graniteware
I'm wondering when or why you would need to use a union. It seems weird to group variables together that are unable to be used together.Strode
@Strode It's useful if you want to be able to store different kinds of data in a single spot. In my answer, I mention my Scheme interpreter - it needed to be able to hold different kinds of atomic data in a single type.Graniteware
@KyleCronin I think I get it. In your case, you have a group of the types, knowing your only going to need to use one but you don't know which one until runtime - so the union allows you to do that. ThanksStrode
@Strode unions can be used as a sort of base class for structs. You can emulate an OO hierarchy using unions of structsToomey
Sounds like union is a good solution for making it behave like in dynamic typing in some way...Cootie
Where it writes byte depends on Endianess? @KyleCroninMyrticemyrtie
@Lazar Byte order in multi-byte types depends on endianness. I suggest reading the Wikipedia article on it.Graniteware
@KyleCronin Is this a right way of thinking about unions : to access the entire four bytes of a given chunk of memory, use x.a and to access only the last (or first?) byte, use x.b? It then means that the fields of a union are just aliases for referencing to some selected portion of a chunk of memory.Aedes
@KyleCronin Integer overflow here? x.a = 387439;? 387439 is bigger than int can hold, causing undefined behavior, sure it is going to behave different.Coenzyme
S
95

Here's the short answer: a struct is a record structure: each element in the struct allocates new space. So, a struct like

struct foobarbazquux_t {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

allocates at least (sizeof(int)+sizeof(long)+sizeof(double)+sizeof(long double)) bytes in memory for each instance. ("At least" because architecture alignment constraints may force the compiler to pad the struct.)

On the other hand,

union foobarbazquux_u {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

allocates one chunk of memory and gives it four aliases. So sizeof(union foobarbazquux_u) ≥ max((sizeof(int),sizeof(long),sizeof(double),sizeof(long double)), again with the possibility of some addition for alignments.

Seidel answered 6/12, 2008 at 18:32 Comment(0)
M
64

Is there any good example to give the difference between a 'struct' and a 'union'?

An imaginary communications protocol

struct packetheader {
   int sourceaddress;
   int destaddress;
   int messagetype;
   union request {
       char fourcc[4];
       int requestnumber;
   };
};

In this imaginary protocol, it has been sepecified that, based on the "message type", the following location in the header will either be a request number, or a four character code, but not both. In short, unions allow for the same storage location to represent more than one data type, where it is guaranteed that you will only want to store one of the types of data at any one time.

Unions are largely a low-level detail based in C's heritage as a system programming language, where "overlapping" storage locations are sometimes used in this way. You can sometimes use unions to save memory where you have a data structure where only one of several types will be saved at one time.

In general, the OS doesn't care or know about structs and unions -- they are both simply blocks of memory to it. A struct is a block of memory that stores several data objects, where those objects don't overlap. A union is a block of memory that stores several data objects, but has only storage for the largest of these, and thus can only store one of the data objects at any one time.

Meemeece answered 8/12, 2008 at 1:54 Comment(1)
suppose you have a packetheader ph; how do you access requestnumber? ph.request.requestnumber ?Aube
H
39

As you already state in your question, the main difference between union and struct is that union members overlay the memory of each other so that the sizeof of a union is the one , while struct members are laid out one after each other (with optional padding in between). Also an union is large enough to contain all its members, and have an alignment that fits all its members. So let's say int can only be stored at 2 byte addresses and is 2 bytes wide, and long can only be stored at 4 byte addresses and is 4 bytes long. The following union

union test {
    int a;
    long b;
}; 

could have a sizeof of 4, and an alignment requirement of 4. Both an union and a struct can have padding at the end, but not at their beginning. Writing to a struct changes only the value of the member written to. Writing to a member of an union will render the value of all other members invalid. You cannot access them if you haven't written to them before, otherwise the behavior is undefined. GCC provides as an extension that you can actually read from members of an union, even though you haven't written to them most recently. For an Operation System, it doesn't have to matter whether a user program writes to an union or to a structure. This actually is only an issue of the compiler.

Another important property of union and struct is, they allow that a pointer to them can point to types of any of its members. So the following is valid:

struct test {
    int a;
    double b;
} * some_test_pointer;

some_test_pointer can point to int* or double*. If you cast an address of type test to int*, it will point to its first member, a, actually. The same is true for an union too. Thus, because an union will always have the right alignment, you can use an union to make pointing to some type valid:

union a {
    int a;
    double b;
};

That union will actually be able to point to an int, and a double:

union a * v = (union a*)some_int_pointer;
*some_int_pointer = 5;
v->a = 10;
return *some_int_pointer;    

is actually valid, as stated by the C99 standard:

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:

  • a type compatible with the effective type of the object
  • ...
  • an aggregate or union type that includes one of the aforementioned types among its members

The compiler won't optimize out the v->a = 10; as it could affect the value of *some_int_pointer (and the function will return 10 instead of 5).

Heliotrope answered 6/12, 2008 at 18:21 Comment(0)
B
20

A union is useful in a couple scenarios. union can be a tool for very low level manipulation like writing device drivers for a kernel.

An example of that is dissecting a float number by using union of a struct with bitfields and a float. I save a number in the float, and later I can access particular parts of the float through that struct. The example shows how union is used to have different angles to look at data.

#include <stdio.h>                                                                                                                                       

union foo {
    struct float_guts {
        unsigned int fraction : 23;
        unsigned int exponent : 8;
        unsigned int sign     : 1;
    } fg;
    float f;
};

void print_float(float f) {
    union foo ff;
    ff.f = f;
    printf("%f: %d 0x%X 0x%X\n", f, ff.fg.sign, ff.fg.exponent, ff.fg.fraction);

}

int main(){
    print_float(0.15625);
    return 0;
}

Take a look at single precision description on wikipedia. I used the example and the magic number 0.15625 from there.


union can also be used to implement an algebraic data type that has multiple alternatives. I found an example of that in the "Real World Haskell" book by O'Sullivan, Stewart, and Goerzen. Check it out in the The discriminated union section.

Cheers!

Biparietal answered 6/9, 2013 at 20:26 Comment(0)
B
12

Yes, the main difference between struct and union is same as you stated. Struct uses all the memory of its member and union uses the largest members memory space.

But all the difference lies by the usage need of the memory. Best usage of the union can be seen in the processes of unix where we make use of signals. like a process can act upon only one signal at a time. So the general declaration will be:

union SIGSELECT
{
  SIGNAL_1 signal1;
  SIGNAL_2 signal2;
  .....
};

In this case, process make use of only the highest memory of all signals. but if you use struct in this case, memory usage will be sum of all signals. Makes a lot of difference.

To summarize, Union should be selected if you know that you access any one of the member at a time.

Biamonte answered 3/1, 2013 at 2:43 Comment(0)
K
11

"union" and "struct" are constructs of the C language. Talking of an "OS level" difference between them is inappropriate, since it's the compiler that produces different code if you use one or another keyword.

Kraemer answered 6/12, 2008 at 18:6 Comment(0)
C
11

You have it, that's all. But so, basically, what's the point of unions?

You can put in the same location content of different types. You have to know the type of what you have stored in the union (so often you put it in a struct with a type tag...).

Why is this important? Not really for space gains. Yes, you can gain some bits or do some padding, but that's not the main point anymore.

It's for type safety, it enables you to do some kind of 'dynamic typing': the compiler knows that your content may have different meanings and the precise meaning of how your interpret it is up to you at run-time. If you have a pointer that can point to different types, you MUST use a union, otherwise you code may be incorrect due to aliasing problems (the compiler says to itself "oh, only this pointer can point to this type, so I can optimize out those accesses...", and bad things can happen).

Contractor answered 6/12, 2008 at 18:30 Comment(0)
A
11

Non technically speaking means :

Assumption: chair = memory block , people = variable

Structure : If there are 3 people they can sit in chair of their size correspondingly .

Union : If there are 3 people only one chair will be there to sit , all need to use the same chair when they want to sit .

Technically speaking means :

The below mentioned program gives a deep dive into structure and union together .

struct MAIN_STRUCT
{
UINT64 bufferaddr;   
union {
    UINT32 data;
    struct INNER_STRUCT{
        UINT16 length;  
        UINT8 cso;  
        UINT8 cmd;  
           } flags;
     } data1;
};

Total MAIN_STRUCT size =sizeof(UINT64) for bufferaddr + sizeof(UNIT32) for union + 32 bit for padding(depends on processor architecture) = 128 bits . For structure all the members get the memory block contiguously .

Union gets one memory block of the max size member(Here its 32 bit) . Inside union one more structure lies(INNER_STRUCT) its members get a memory block of total size 32 bits(16+8+8) . In union either INNER_STRUCT(32 bit) member or data(32 bit) can be accessed .

Adelinaadelind answered 16/12, 2015 at 6:4 Comment(0)
T
10

A structure allocates the total size of all elements in it.

A union only allocates as much memory as its largest member requires.

Tallboy answered 6/12, 2008 at 17:58 Comment(1)
You might want to also add that union members "overlay" each other in that they all start at the beginning address of the allocated union "structure".Raiment
C
4

what is the difference between structure and union?

Short cut answer is: The deference is in memory allocation. Explanation: In structure, memory space will be created for all members inside structure. In union memory space will be created only for a member which needs largest memory space. Consider the following code:

struct s_tag
{
   int a; 
   long int b;
} x;

union u_tag
{
   int a; 
   long int b;
} y;

Here there are two members inside struct and union: int and long int. Memory space for int is: 4 byte and Memory space for long int is: 8 in 32 bit operating system.

So for struct 4+8=12 bytes will be created while 8 bytes will be created for union

Code example:

#include<stdio.h>
struct s_tag
{
  int a;
  long int b;
} x;
union u_tag
{
     int a;
     long int b;
} y;
int main()
{
    printf("Memory allocation for structure = %d", sizeof(x));
    printf("\nMemory allocation for union = %d", sizeof(y));
    return 0;
}

Ref:http://www.codingpractise.com/home/c-programming/structure-and-union/

Cranston answered 4/1, 2018 at 7:26 Comment(0)
A
3

A structure is a collection of different data types, where different types of data can reside in it and every one get its own block of memory.

We usually use a union when we are sure that only one of the variables will be used at once and you want full utilization of present memory, because it gets only one block of memory which is equal to the largest type.

struct emp
{
    char x; //1 byte
    float y; //4 byte
} e;

Total memory it gets: =>5 bytes.

union emp
{
    char x; //1 byte
    float y; //4 byte
} e;

Total memory it gets: 4 bytes.

Affright answered 30/6, 2014 at 9:27 Comment(0)
L
3

The uses of union Unions are used frequently when specialized type conversations are needed. To get an idea of the usefulness of union. The c/c standard library defines no function specifically designed to write short integers to a file. Using fwrite() incurs encurs excessive overhead for simple operation. However using a union you can easily create a function which writes binary of a short integer to a file one byte at a time. I assume that short integers are 2 byte long

THE EXAMPLE:

#include<stdio.h>
union pw {
short int i;
char ch[2];
};
int putw(short int num, FILE *fp);
int main (void)
{
FILE *fp;
fp fopen("test.tmp", "wb ");
putw(1000, fp); /* write the value 1000 as an integer*/
fclose(fp);
return 0;
}
int putw(short int num, FILE *fp)
{
pw word;
word.i = num;
putc(word.c[0] , fp);
return putc(word.c[1] , fp);
}    

although putw() i called with short integer, it was possble to use putc() and fwrite(). But i wanted to show an example to dominstrate how a union can be used

Lory answered 13/7, 2014 at 10:12 Comment(0)
T
2

Unions come handy while writing a byte ordering function which is given below. It's not possible with structs.

int main(int argc, char **argv) {
    union {
        short   s;
        char    c[sizeof(short)];
    } un;

    un.s = 0x0102;

    if (sizeof(short) == 2) {
        if (un.c[0] == 1 && un.c[1] == 2)
            printf("big-endian\n");
        else if (un.c[0] == 2 && un.c[1] == 1)
            printf("little-endian\n");
        else
            printf("unknown\n");
    } else
        printf("sizeof(short) = %d\n", sizeof(short));

    exit(0);
}
// Program from Unix Network Programming Vol. 1 by Stevens.
Tova answered 4/11, 2013 at 19:41 Comment(0)
M
1

A Union is different from a struct as a Union repeats over the others: it redefines the same memory whilst the struct defines one after the other with no overlaps or redefinitions.

Messapian answered 6/12, 2008 at 17:56 Comment(0)
H
1

It is recommended to use structures when we need to model something which has a group of independent attributes and unions should be used when an entity has many forms and it can exist in only one form at a time.

Let us look at 2 places where they could be applied

You need to store and update values of a car. In order to do so we need to record all the attributes of a car like model, mileage, price and fuel type. These values are always present in a car and they do not depend on other values. Hence we require a data type that not only stores all our attributes but also ensures their proper updation. Such types of tasks can be done using structures.

struct car{
    char model[];
    int mileage;
    int price;
    char fuel_type[];
};

An organization needs to collect your data for payment verification from a large number of customers. Now for data integrity and customer security an organization is directed to take the least number of details from a person. These details can be either your PAN number or account number or voter id. Now since we need to collect any one of these details and also be memory efficient at the same time we can use union here. It will hold only the single value that is provided to it.

union verification_details{
    char account_number[10];
    char PAN[10];
    char voter_id[10];
};

I found the following article that explains it quite well: Difference Between Structure and Union

Hurricane answered 3/3, 2022 at 7:36 Comment(0)
K
0

Is there any good example to give the difference between a struct and a union?

Real-life example from embedded system application would be the following. It only uses union but it clearly shows the functionality of union.

Write function for I2C communication protocol uses union type, which is used for data storage, when retrieving data from array passed to it.

union data
{
    uint32_t packet;
    uint8_t  packetbyte[4];
} txdata;

Array being passed to the write function via pointer contains elements of a size of one byte. In for loop these bytes are extracted one by one in four steps and stored into individual elements of txdata.packetbyte member.

After end of loop, txdata.packet holds 4 bytes of data, which were being consecutively stored into txdata union. And as final step of sending data over communication bus, txdata.packet is written into 32-bit buffer, which initiates write sequence after being written to. Then reset content by txdata.packet = 0 before next for loop starts executing.

This way I2C master can re-transmit 32-bit packets until passed input data is sent and write function is terminated.

Korey answered 10/3, 2022 at 19:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.