Working with a union of structs in C

50,715

Solution 1

  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
};

Solution 2

  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.
Share:
50,715
rikkit
Author by

rikkit

Updated on July 13, 2022

Comments

  • rikkit
    rikkit almost 2 years

    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.

  • rikkit
    rikkit over 10 years
    So even though TYPEA and TYPEB structs have an int in the first positions, there's no way to access it without knowing which type I'm working with?
  • Arthur
    Arthur over 3 years
    Is malloc for TYPEA or TYPEB needed after mallocing struct some_info?
  • Fraggle
    Fraggle about 2 years
    @Arthur No. The members of data are not pointers so sizeof(data) is at least the larger of sizeof(struct TYPEA) and sizeof(struct TYPEB).