Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working with a union of structs in C

Tags:

c

unions

Say I have the following types:

typedef struct TYPEA
{
    int type;
    char[12] id;
} TYPEA;

typedef struct TYPEB
{
    int type;
    int value;
} TYPEB;

I want to use create a union of these types and 'int', so that I can access the "type" int without needing to know whether TYPEA or TYPEB is stored in the union (the value of int lets me determine which is actually stored there). I can't get the right syntax though.

My union:

typedef union MEMBER
{
    int type;
    struct TYPEA a;
    struct TYPEB b;
} MEMBER;

The union is accessed via:

typedef struct WRAPPER
{
    union MEMBER* member;
    struct WRAPPER* next;
} WRAPPER;

Questions:

  1. (With 'w' as a pointer to an allocated WRAPPER struct) Accessing using w->member->a.id gives "request for member 'id' in something not a structure or union.
  2. Can I assign a pointer to an already malloc'd TYPEA/B to w->member directly? Or does a union need to be malloced specially?

Thanks.

like image 497
rikkit Avatar asked Dec 23 '13 23:12

rikkit


People also ask

Can we use union in structure in C?

A structure can be nested inside a union and it is called union of structures. It is possible to create a union inside a structure.

Why do we use union inside structures in C?

A union is an object similar to a structure except that all of its members start at the same location in memory. A union variable can represent the value of only one of its members at a time. In C++, structures and unions are the same as classes except that their members and inheritance are public by default.


2 Answers

  1. Use w->member->type.
  2. You need to allocate the union specifically.

One note that may be a point of misunderstanding is that the union holds EITHER the int, or TYPEA, or TYPEB, so in particular you cannot rely on your int type; in the union to tell you which struct the union holds.

Edit to respond to question in comments:

You probably want something like this:

struct TYPEA {
  char data[30]; // or whatever
};

struct TYPEB {
  double x, y; // or whatever
};

struct some_info {
  int type; // set accordingly
  union {
    struct TYPEA a;
    struct TYPEB b;
  } data; // access with some_info_object.data.a or some_info_object.data.b
};
like image 130
Andrey Mishchenko Avatar answered Oct 08 '22 15:10

Andrey Mishchenko


  1. You defined the member field as a pointer, so you should use w->member->type instead of w->member.type.
  2. You should malloc the union type. When you allocate a union, you'll get a structure that has a sizeof equal to the largest element in the union. If you try to copy structures into union pointers, you'll mess up the alignment.
like image 42
Zach Rattner Avatar answered Oct 08 '22 15:10

Zach Rattner