Доступ к переменным в объединении внутри структуры - PullRequest
3 голосов
/ 17 июля 2010

Может ли кто-нибудь объяснить, почему первый метод доступа к вложенному элементу структуры внутри объединения в структуре работает, а второй - нет?

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

Ответы [ 3 ]

2 голосов
/ 17 июля 2010

Попробуйте следующее:

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

ПРИМЕЧАНИЕ: Не изменяйте n.u.value узла, если вы уже назначили его дочерние указатели [].Вы перезапишете один из указателей и потеряете эту память, а также потерпите крах, если попытаетесь получить доступ к массиву child [] после этого.Союзы хитры - лучше всего избегать такого рода договоренностей.

1 голос
/ 17 июля 2010

Ваша проблема не имеет ничего общего с тем, что в ней участвует union.

Доступ к неинициализированным указателям дает вам случайное поведение. Иногда это работает, иногда нет. Для вашего первого доступа, возможно, что-то просто произошло в том месте, куда вы заходите.

Просто инициализируйте, а-ля C99:

Node n = { .type = 0 };

или

Node n = { 0 };

а-ля С89, вместо вашего назначения выписка . Это имеет то преимущество, что инициализирует все компоненты, которые не упомянуты в 0, то есть ваши указатели. Тогда ваш тестовый код должен с удовольствием завершиться.

1 голос
/ 17 июля 2010

Любой из этих методов должен подходить для доступа к вложенному элементу структуры внутри объединения, проблема в том, что вы не выделили память для узлов, на которые ссылается child [0] или child [ 1]. (Я удивлен, что твой "1-й метод" тоже не подведет.)

...