2012-08-04 78 views
0

我已經實現鏈表刮鏽了我的開發技能無效讀取,但發現的valgrind我除去中間分子的測試過程中報告大小爲4的無效讀取。鏈表,大小4

==1197== Invalid read of size 4 
==1197== at 0x804885C: main (list.c:135) 
==1197== Address 0x426e76c is 4 bytes inside a block of size 12 free'd 
==1197== at 0x40257ED: free (vg_replace_malloc.c:366) 
==1197== by 0x804875E: list_remove (list.c:112) 
==1197== by 0x8048857: main (list.c:137) 

觸發主代碼是這樣的:

for (iter = l2->head; iter; iter = iter->next) { 
      if (iter->n >= 10 && iter->n <= 14) 
        list_remove(l2, iter); 

刪除功能:

void list_remove(struct list *list, struct node *node) 
{ 
     if (node == list->head && node == list->tail) { 
       list->head = list->tail = NULL; 
     } 
     else if (node == list->head) { 
       list->head = node->next; 
       list->head->prev = NULL; 
     } 
     else if (node == list->tail) { 
       list->tail = node->prev; 
       list->tail = NULL; 
     } 
     else { 
       struct node *prev, *next; 
       prev = node->prev; 
       next = node->next; 
       prev->next = next; 
       next->prev = prev; 
     } 

     free(node); 
} 

的了我所能做的任何想法做錯了嗎?

回答

4

你釋放在循環中的值,然後解引用它來獲得在其「下一個」指針。你需要一個溫度值,這樣做的權利:

for (iter = l2->head; iter; iter = next) { 
      next = iter->next; 
      if (iter->n >= 10 && iter->n <= 14) 
        list_remove(l2, iter); 
    } 
+0

感謝tbert,這是非常有幫助! :) – CaseyJones 2012-08-04 22:01:53

1

你釋放iter指針,當你free(node)。然後,您嘗試從iter->next中讀取不再存在的內容。

+0

謝謝Bitmask,這是非常有用的:) – CaseyJones 2012-08-04 22:02:20

0

HHM ...所有你需要做的,是的Valgrind的消息。

  • 無效;在這裏讀到:main (list.c:135) - 這是iter->next
  • 從釋放的位置,這裏的內存釋放:list_remove (list.c:112),這是free(node);

刪除之前剛剛緩存的下一個指針。

+0

謝謝。我不明白究竟發生了什麼,因爲135行中至少有2個讀數。 – CaseyJones 2012-08-04 22:04:51

+0

所以呢?添加一些跟蹤消息,你會看到。 – 2012-08-04 22:37:12