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?
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.
union
is a good solution for making it behave like in dynamic typing in some way... –
Cootie 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 x.a = 387439;
? 387439
is bigger than int
can hold, causing undefined behavior, sure it is going to behave different. –
Coenzyme 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.
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.
packetheader ph;
how do you access requestnumber? ph.request.requestnumber
? –
Aube 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
).
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!
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.
"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.
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).
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 .
A structure allocates the total size of all elements in it.
A union only allocates as much memory as its largest member requires.
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/
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.
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
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.
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.
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
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.
© 2022 - 2024 — McMap. All rights reserved.