2014-12-03 97 views
-2

我的C程序功能有問題。功能的想法是添加一個項目(newval)到鏈表的末尾。這裏是我的代碼(也找到它的註釋):將項目添加到鏈接列表的末尾 - >錯誤

#include <stdlib.h> 

struct list 
{ 

    int val; 
    struct list *next; 
}; 

void add_to_list(struct list *l, int newval) 

{ 

    if (!l) return; //my fried said that I should add this, but I dont really understand why. 
        //and should it be if(l == NULL) rather than if(!l)? 
    while(l->next !=NULL) // I am pretty sure that this while loop is correct 
     l=l->next; 
    l->next = malloc(sizeof(int)) //hmm... is this correct way to allocate memory 
    l->next->val = newval; //not sure about this 
    l->next->next = NULL; //This should be fine 
} 
+0

'l-> next = malloc(sizeof(int))'這確實是分配內存的正確方法,但是分配不夠。你需要分配足夠的包含一個完整的'struct list'。將此行更改爲'l-> next = malloc(sizeof(*(l-> next)))' – 2014-12-03 17:06:23

回答

0

應分配

l->next = malloc(sizeof(struct list)); 

代替

l->next = malloc(sizeof(int)); 

並初始化爲零分配的內存:

memset(l->next, 0, sizeof(struct list)); 
+0

我不同意。爲什麼要使用memset()來初始化結構?這並不足以證明這一點。 – 2014-12-03 22:47:29

+0

好吧,我沒有看到行 - > next-> next = NULL - > memset在這種情況下是冗餘的。我只是想確保一切都已正確初始化。就我所知,memset對內存塊(1字節)的最小可能大小工作正常。 – chrmue 2014-12-04 08:12:04

2
l->next = malloc(sizeof(int)); 

您需要分配內存的結構不適合int

l->next = malloc(sizeof(struct list)); 

if(!l)是相同if(l == NULL)

+0

如果(!l)與if(l == NULL)確實相同。我認爲如果(!l)表示if(l == 0)? – 2014-12-03 18:17:22

+0

@NerdBergg NULL是0.檢查這個http://stackoverflow.com/questions/1296843/what-is-the-difference-between-null-0-and-0 – Gopi 2014-12-03 18:18:52

+0

好吧,這是明確的,但是,然後再次,爲什麼如果在這裏判刑,這麼做呢?我的意思是,劑量這個檢查,如果列表是空的,然後返回。但爲什麼要返回,如果列表是空的,我們仍然不能添加一個項目newval?或者這意味着,如果列表是空的,我們不能添加任何東西來結束它......我們應該首先添加第一個項目,這將不得不在不同的功能? – 2014-12-03 19:13:56

0
void add_to_list(struct list *l, int newval) 

你的函數聲明爲void。這意味着您的功能無法通過 發送錯誤信號。樣本代碼不是問題, 但絕對是你至少應該知道的東西。

if (!l) return; //my fried said that I should add this, 
        //and should it be if(l == NULL) rather than if(!l)? 

的構建(!l)是完全等效於(l != NULL)。這 是因爲NULL被定義爲「一個空指針恆定」和 「空指針常數」爲「與 一個整數常量表達式的值爲0,或這樣的鑄造的表達式來鍵入void *」 。在其他 單詞中,NULL評估爲零。

while(l->next !=NULL) // I am pretty sure that this while loop is correct 
     l=l->next; 

是的,這個while循環是正確的。當循環完成時,l將 指向列表中的最後一個元素。

l->next = malloc(sizeof(int)) //hmm... is this correct way to allocate memory 

您的分配幾乎是正確的。您正在分配足夠的存儲空間到 ,您需要一個int,但您確實需要足夠的存儲空間來存放一個 struct list。改爲使用l->next = malloc(sizeof(struct list));

l->next->val = newval; //not sure about this 

這裏沒有錯誤。這與下一行完全一樣。

l->next->next = NULL; //This should be fine 

是的,這很好..


然而,雖然這部分代碼大多是正確的,除非這是已經涵蓋了malloc()

l->next = malloc(sizeof(int)) //hmm... is this correct way to allocate memory 
    l->next->val = newval; //not sure about this 
    l->next->next = NULL; //This should be fine 

這裏使用的方法略有不同尋常。這是因爲 在分配新內存時,您將指針 直接分配給l->next,然後對其進行初始化。

什麼是更常見的做是todeclare指針如 struct list *tmp = NULL的功能, 的開始和分配時,分配新的內存tmp。然後, 初始化tmp和 指向的新列表元素,然後將現在初始化的新列表元素添加到列表的末尾 。雖然這涉及更多的代碼,但它分離了創建新列表元素 和將元素添加到列表末尾的兩個步驟。

void add_to_list(struct list *l, int newval) 
    { 
     struct list *tmp = NULL; 

     if (!l) return; // If no valid list, return. 

     tmp = malloc(sizeof(struct list)); // Allocate new list element 
     tmp->val = newval;     // and fill it up. 
     tmp->next = NULL; // End of the list always points nowhere. 

     while(l->next !=NULL) // find end of list. 
      l=l->next; 

     l->next = tmp; // Attach new list element to end. 

     return; 
    } 

而且,做這種方式避免了從通過l->next指針賦值,出現 的潛在的混亂。