2010-07-17 64 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,因此是您的指針。然後,您的測試代碼應該從此以後愉快地發生段錯誤。