2012-06-05 29 views
0

我試圖在C中創建一個鏈接列表,但程序因某些神祕故障而崩潰。創建鏈接列表時的神祕分段錯誤(添加功能)

首先我嘗試這樣做:

typedef struct product_data product_data; 

struct product_data { 
int product_code; 
int product_size; 
product_data *next; 
}; 

product_data *products_head = NULL; 
product_data *products_tail = NULL; 

int main() { 
    int newcode = 5; 
    int newsize = 5; 
    products_head->product_code = newcode; 
    products_head->product_size = newsize; 
    products_head->next = NULL; 

    return 0; 
} 

不幸的是,程序崩潰,沒有任何錯誤信息。

然後,我改變了一些地方:

typedef struct product_data product_data; 

struct product_data { 
int product_code; 
int product_size; 
product_data *next; 
}; 

product_data *products_head = NULL; 
product_data *products_tail = NULL; 

int main() { 
    product_data *newproduct; 
    int newcode = 5; 
    int newsize = 5; 
    newproduct->product_code = newcode; 
    newproduct->product_size = newsize; 
    newproduct->next = NULL; 

    products_head = newproduct; 

    return 0; 
} 

沒有崩潰這次,它似乎工作。但我不知道爲什麼。

任何想法?

在此先感謝!

+1

必須是最近的家庭作業... – 2012-06-05 19:42:39

+0

必須讓你失望 - 沒有作業。 ;-)不幸的是我不再那麼年輕...... – user1438181

+0

不是故意侮辱;這些問題只是「批量」出現:-) – 2012-06-06 18:21:57

回答

4

它並不真正的工作。你還在取消引用無效指針:

product_data *newproduct; 
int newcode = 5; 
int newsize = 5; 
newproduct->product_code = newcode; 
newproduct->product_size = newsize; 
newproduct->next = NULL; 

不過,雖然在第一個版本你解引用指針明確設置爲NULL,它分段故障墜毀像它應該。在這裏,您正在取消引用包含堆棧中所有數據的指針,但不幸的是它不會崩潰。這是未定義的行爲,所以它不一定會崩潰。

你必須讓你的指針指向有效的內存,

newproduct = malloc(sizeof product_data); 
+0

謝謝!現在明白了。 :-) – user1438181

1

您需要爲products_head分配內存。現在你只是將它設置爲NULL。要麼不使它成爲指針,要麼使用malloc。

1

在第一個樣品,你正在寫一個NULL指針。在取消引用之前,您需要爲products_head分配空間。像

products_head = malloc(sizeof(product_data)); 

我不知道你的第二個例子爲什麼工作。它不應該。 newproduct是一個未初始化的變量,它可以指向任何地方。也許你很幸運,它指向一個未使用的有效內存塊。

0

這將工作,直到它不。你仍然沒有爲你的結構分配任何內存。但由於運氣好,新產品指向一些有效的內存位置。您正面臨的問題是,product_head被手動設置爲null(儘管這不是必需的,因爲所有全局變量總是被初始化)。然而,堆棧變量沒有初始化,並且你很幸運(或者不幸的是,它會導致你錯過一個明顯的編程錯誤),它碰巧指向你的地址空間中有效的地方。

您可以使用printf(「%p」,newproduct)打印新產品的內容以查看它指向的位置;不幸的是,插入這一行可能會改變程序的行爲。

0

「 - >」用於訪問動態分配的結構中的元素,「。」用於訪問靜態分配的結構中的元素。

下面是一個例子:

typedef struct product_data product_data; 

struct product_data { 
    int product_code; 
    int product_size; 
    product_data *next; 
}; 

product_data *products_head = NULL; 
product_data *products_tail = NULL; 

int main() { 
    /* Allocate memory */ 
    product_data *newproduct = malloc(sizeof(product_data)); 
    int newcode = 5; 
    int newsize = 5; 

    products_head = newproduct; 
    newproduct->product_size = newsize; 
    newproduct->next = NULL; 

    /* free memory */ 
    free(product_data); 

    return 0; 
} 

但請記住,所有的新節點您在鏈表讓你將不得不分配內存和自由內存。一個很好的程序可以用來檢查你分配的所有內存是否已經釋放了valgrind。如果你遇到邏輯錯誤試圖使鏈表先畫出來的手是這樣的:

 [head] [tail] 
     |  | 
     V  V 
     [ a ] -> [ b ] -> null 

只要記住,頭部和尾部都是指針(所以他們並不需要分配內存,它們只需要在你想要的節點上進行POINTING

如果你仍然遇到問題,因爲你的邏輯變得非常複雜我建議你嘗試學習GDB(它是一個命令行調試器)它會幫助你逐步通過你的所以你可以一步一步看到發生了什麼,這就是我最初學會創建數據結構的原因。

祝你好運!