Nitzs
Nitzs

Reputation: 31

Accessing variables in a union inside a struct

Can anyone please explain why the 1st method of accessing a nested struct element inside an union in a struct works and the 2nd does not?

typedef struct element Node;
struct element
{
    int type;
    union
    {
        int value;
        Node *child[2];
    } u;
};
int main()
{
    Node n;
    Node *p;    
    n.type = 0;
    p = n.u.child[0];
    p->type = 10;  // 1st method
    (n.u.child[1])->type = 24;   // 2nd method
    return 0;
}

Upvotes: 3

Views: 35882

Answers (3)

Jens Gustedt
Jens Gustedt

Reputation: 78953

Your problem has not much to do with the fact that there are unions involved.

Accessing uninitialized pointers just gives you random behavior. Sometimes it does work sometimes not. For your first access probably something just luckily happened to be in the place that you access.

Just initialize, à la C99:

Node n = { .type = 0 };

or

Node n = { 0 };

à la C89, instead of your assignment statement. This has the advantage to initialize all components that are not mentioned to 0, thus your pointers. Then your test code should segfault happily ever after.

Upvotes: 1

Amardeep AC9MF
Amardeep AC9MF

Reputation: 19054

Try the following:

int main()
{
    Node n;
    Node *p;    
    n.type = 0;

    // allocate memory for child nodes
    n.u.child[0] = (Node *)malloc(sizeof(Node));

    if (n.u.child[0] == NULL)
    {
        return 1;
    }

    n.u.child[1] = (Node *)malloc(sizeof(Node));

    if (n.u.child[1] == NULL)
    {
        free(n.u.child[0]);
        return 1;
    }

    p = n.u.child[0];
    p->type = 10;  // 1st method
    (n.u.child[1])->type = 24;   // 2nd method

    // release dynamically allocated memory
    free(n.u.child[0]);
    free(n.u.child[1]);

    return 0;
}

NOTE: Don't modify n.u.value of a Node if you've already assigned its child[] pointers. You will overwrite one of the pointers and leak that memory as well as crash if you try to access the child[] array after that. Unions are tricky -- best to avoid this sort of arrangement.

Upvotes: 2

Mark Elliot
Mark Elliot

Reputation: 77084

Either of those methods should be fine for accessing a nested struct element inside a union, the issue here is that you haven't allocated memory for the nodes referred to by child[0] or child[1]. (I'm surprised your "1st method" doesn't fail, too.)

Upvotes: 1

Related Questions