2013-06-28 66 views
1

考慮下面的代碼片段中分配的內存Ç - 無法鏈表結構

struct node { 
    char *name; 
    int m1; 
    struct node *next; 
    }; 

    struct node* head = 0; //start with NULL list 

    void addRecord(const char *pName, int ms1) 
    { 
     struct node* newNode = (struct node*) malloc(sizeof(struct node)); // allocate node 

     int nameLength = tStrlen(pName); 
     newNode->name = (char *) malloc(nameLength); 
     tStrcpy(newNode->name, pName); 

     newNode->m1 = ms1; 
     newNode->next = head; // link the old list off the new node 
     head = newNode; 
    } 

    void clear(void) 
    { 
     struct node* current = head; 
     struct node* next; 
     while (current != 0) 
     { 
      next = current->next; // note the next pointer 
    /*  if(current->name !=0) 
      { 
       free(current->name); 
      } 
    */ 
      if(current !=0) 
      { 
       free(current); // delete the node 
      } 
      current = next; // advance to the next node 
     } 
     head = 0; 
    } 

問: 我不能釋放電流 - >名字,只有當我評論姓名的釋放,程序工作。 如果我取消當前名稱的空閒部分的註釋,我會在Visual Studio窗口中看到Heap腐敗錯誤。 我怎樣才能釋放名字?

回覆:

@一切,是的,有在結構聲明錯別字。應該是char *名稱,然後是struct node *。看起來stackoverflow編輯拿走了這兩個明星。

該問題已通過執行malloc(nameLength + 1)來解決。 但是,如果我嘗試在命令提示符上運行舊代碼(malloc(namelength))而不是在Visual Studio上運行,它運行良好。 看起來,有一些編譯器正在嚴格檢查。

我仍然不明白的一件事是,free不需要NULL終止指針,而覆蓋已分配指針的機會在這裏非常小。

user2531639又名Neeraj

+0

我想,在節點名稱應該是字符*? –

+0

[不要在C]中輸入'malloc()'的返回值(http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)。 – unwind

回答

6

這是編寫超出了分配內存的結束,因爲對於空終止字符沒有空間,從而導致未定義的行爲:

newNode->name = (char *) malloc(nameLength); 
tStrcpy(newNode->name, pName); 

要糾正:

newNode->name = malloc(nameLength + 1); 
if (newNode->name) 
{ 
    tStrcpy(newNode->name, pName); 
} 

注意調用free()NULL指針是安全的,因此在調用它之前檢查NULL是多餘的:

free(current->name); 
free(current); 

此外,我認爲有錯別字的發佈struct定義(如各類namenext應該是指針):

struct node { 
    char* name; 
    int m1; 
    struct node* next; 
}; 
+0

我同意分配沒有留下適當的NULL空間,但我認爲這種情況下緩衝區實際上被覆蓋的可能性不大。 malloc真正的緩衝區大小通常至少比在這裏超過的一個字節大。錯誤的代碼,當然,但我認爲這不是OP的失敗原因。話雖如此,我假設'name'是一個'char *',而不是上面提供的'char'。 – mah

+0

它可能會劃出額外的空間,但這並不意味着'free'不會檢查額外的空間進行修改。 –

+0

如果'char name;'不是拼寫錯誤,它會強烈參與保持'free(current-> name')的工作狀態,但是我不確定'malloc()'是否可以編譯。 – alk