2010-07-17 60 views
3

谁能请解释为什么在一个结构工程访问一个联盟内部嵌套结构元素的第一个方法和第二个不里面?访问变量的联合的结构

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

当你写一个问题,也有一些简洁和有用的格式化指令只是问题框右侧。请在下次阅读。 – 2010-07-17 11:18:03

+0

这是什么意思“不起作用”?编译错误?运行时错误? – pmod 2010-07-17 11:35:21

+0

如果仅在第二种方法中出现“分段错误”(在两种方法中都会出现这种情况),则不起作用。 – Nitzs 2010-07-17 11:42:35

回答

1

无论这些方法应该罚款访问工会内部嵌套结构元素,这里的问题是,你有没有通过孩子所指的节点分配的内存[0]或儿童[ 1]。 (我很惊讶你的“第一次法”并没有失败,太。)

+0

第一种方法确实有效,这就是为什么当第二种方法没有时会感到困惑的原因。 – Nitzs 2010-07-17 11:26:24

2

尝试以下操作:

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如果你已经分配了其子[]指针。你将覆盖其中一个指针并泄漏该内存,如果你尝试访问后面的子[]数组,就会崩溃。工会很棘手 - 最好避免这种安排。

+0

感谢您的回复,Amardeep。我知道在访问它之前需要将内存分配给指针对象。但是在这种情况下,如果没有为任何一个子节点分配任何内存,为什么第二种方法在理想情况下都应该失败。 – Nitzs 2010-07-17 11:39:00

+0

ANSI C不会初始化您在堆栈上分配的结构。所以数组n.u.child []包含两个带有不确定值的指针。只是碰巧,child [0]包含一个值,指向一个内存地址,当您解除引用并写入它时不会导致崩溃。你不能指望这种行为,你不知道什么是你做这个任务时损坏的。 – 2010-07-17 11:47:07

1

您的问题不多做的事实,但它牵涉到union秒。

访问未初始化的指针,只是给你随机的行为。有时它有时不工作。对于你的第一次访问可能只是幸运地发生在你访问的地方。

只是初始化,点菜C99:

Node n = { .type = 0 }; 

Node n = { 0 }; 

点菜C89, ,而不是你的任务声明。这有利于将所有未提及的组件初始化为0,因此是您的指针。然后,您的测试代码应该从此以后愉快地发生段错误。