how union is different then structure in context of memory

Thread Starter

anukalp

Joined Jul 28, 2018
158
Hello

I'm trying to understand how union is different then structure in context of memory in c language

Example for structure
C:
struct student{
    int roll_number;
    float mark ;
}record;
Example for union
C:
union student{
    int roll_number;
    float mark ;
}record;
Can anyone help me to understand how union is different then structure in context of memory in c language ?
 

MrSoftware

Joined Oct 29, 2013
2,273
In a structure, each of the elements gets their own memory. So your record.roll_number and record.mark are separate. In a union, all elements share the same memory. So in case of your union, your record.roll_number and record.mark actually point to the same starting memory address. With the union, if you assign record.roll_number = 1, then assign record.mark = 2.5, the assignment of record.mark will overwrite the value in record.roll_number.

Write your program using each, open the memory watch in your debugger and watch the memory change as you step through the code.
 
Last edited:

Thread Starter

anukalp

Joined Jul 28, 2018
158
In a structure, each of the elements gets their own memory. So your record.roll_number and record.mark are separate. In a union, all elements share the same memory.

Write your program using each, open the memory watch in your debugger and watch the memory change as you step through the code.
I didn't understand
consider example
C:
union student
{
    int roll_number;
    float mark ;
}record;
memory space
0001
0002
0003
0004
.......

0010

how the union will allocate memory space ?

I have MinGW and it works great. I just don't know how to use the debugger. I have looked for documentation on this and found nothing.
 
Last edited:

WBahn

Joined Mar 31, 2012
32,823
As MrSoftware said, a union will lay the elements over each other in the same memory. If you use a structure and your int data type is four bytes (and float is pretty much always four bytes), then the structure will require eight bytes (minimum) and both members have their own memory within that space. If you use a union, then the entire object will probably require just four bytes because both data members are assigned to the same four bytes of memory, meaning that you can only use one at a type.

Unions are useful when you need to store different types of data at different times, but only one type at any given time. They are also very dangerous from a bug and security standpoint.
 

Thread Starter

anukalp

Joined Jul 28, 2018
158
As MrSoftware said, a union will lay the elements over each other in the same memory. If you use a structure and your int data type is four bytes (and float is pretty much always four bytes), then the structure will require eight bytes (minimum) and both members have their own memory within that space..
assume int data type take four bytes and float data type take four bytes

int roll_number = 0010;
float mark = 35.50

then the structure will require eight bytes and both members have their own memory within that eight bytes space.

meaning that you can only use one at a type..
What do you mean by this line ?
 

MrSoftware

Joined Oct 29, 2013
2,273
I didn't understand
consider example
C:
union student
{
    int roll_number;
    float mark ;
}record;
memory space
0001
0002
0003
0004
.......

0010

how the union will allocate memory space ?

I have MinGW and it works great. I just don't know how to use the debugger. I have looked for documentation on this and found nothing.
You really need to figure out the debugger, learning C without a debugger is going to be very painful. What platform are you on? If you have Windows available, download the free version of Microsoft Visual Studio. The Visual Studio debugger is fantastic and makes watching memory very easy. Else you can use gdb on the command line, or check out Eclipse which I believe will give you a GUI on top of gdb; it's not going to be as nice as Visual Studio, but it's better than nothing.

If you want to do it the painful way with some printf's; in code, declare the struct then print the address of each of the members in the struct. Then declare the union and print the address of each of the members of the union. With the struct every element will have a different address. In the union the addresses will all match.

Think of your union like this:
  1. union student
  2. {
  3. int roll_number;
  4. float mark ;
  5. }record;

This is more or less the same as doing this (pseudo code):

byte memory_space[4];
int *roll_number = (int*)&memory_space[0];
float *mark = (float*)&memory_space[0];
 
Last edited:

MrSoftware

Joined Oct 29, 2013
2,273
I stumbled on this, which is too cool for words. It uses gdb for debugging:

https://www.onlinegdb.com/online_c_compiler

Code:
#include <stdio.h>

struct{
    int my_int;
    float my_float;
}mystruct;

union{
    int my_int;
    float my_float;
}myunion;


int
main ()
{
  printf("mystruct.my_int:  0x%d\n", &mystruct.my_int);
  printf("mystruct.my_float:  0x%d\n", &mystruct.my_float);

  printf("myunion.my_int:  0x%d\n", &myunion.my_int);
  printf("myunion.my_float:  0x%d\n", &myunion.my_float);

  return 0;
}
upload_2018-10-10_11-56-41.png

upload_2018-10-10_11-56-57.png


The GDB output is even better, it tells you explicitly that the float is 4 byte past the int in the struct, but the same address in the union:

upload_2018-10-10_12-1-0.png
 

Attachments

WBahn

Joined Mar 31, 2012
32,823
assume int data type take four bytes and float data type take four bytes

int roll_number = 0010;
float mark = 35.50

then the structure will require eight bytes and both members have their own memory within that eight bytes space.


What do you mean by this line ?
Simple -- if you use the four bytes to store an int, you can't ALSO use it to store a float AT THE SAME TIME. Your program has to chose -- but it can change that choice as often as needed.

So initially I might store an int in it by saying

student.roll_number = 10;

That means that the pattern of thirty-two bits stored in those four memory locations is consistent with a four-byte two's complement integer.

But at some later type you might execute the statement

student.mark = 35.50;

and now the pattern of thirty-two bits stored in those four memory locations is consistent with a four-byte IEEE-754 single-precision floating point number.

If you now try to do something like:

roll_total = student.roll_number;

you will get an incorrect result because the statement will interpret those 32-bits as a two's complement integer.
 
Top