2011-04-20 69 views
0

我正在通過一些C練習(新手)我碰到了一些問題。我獲得了先進先出隊列,並告訴將修改remove函數爲FILO。 ((void *)p);這可以很好地工作。在while循環中,我從前面的方法中取出了這一行。任何人都可以告訴我爲什麼當這條線在那裏時不起作用?我猜我不能刪除它由於內存泄漏entirly?在C中使用free()

/* remove next Item from queue, placing it in the 2nd argument; 
* return 1/0 if successful/queue empty */ 

int q_remove(Queue *q, Item i) { 
struct q_element *p; 
if (q->head == NULL) 
    return 0; 
if(q->head==q->tail){ 
    p=q->head; 
    q->head=NULL; 
    q->tail=NULL; 
    memcpy(i, p->value, q->size); 
    free(p->value); 
    free((void *) p); 
    return 1; 
} 
p=q->head; 
while(p != NULL){ 
    if(p->next==q->tail){ 
     memcpy(i, p->next->value, q->size); 
     free(p->next->value); 
     q->tail=p; 
     q->tail->next=NULL; 
     free((void *) p); 
     return 1; 


    } 
    p=p->next; 

} 

return 0; 
} 
+0

對不起,但這不能編譯。請提供您參考的代碼,不作任何修改。 – 2011-04-20 14:45:52

+1

刪除轉換爲(void *),調用free()時不需要。 – unwind 2011-04-20 14:47:00

回答

1

該行:

q->tail->next=NULL; 
free((void *) p); 

...可能應該是

free(free((void *) p->next); 
p->next=NULL; 

因爲你不是要免費'p'(這是你的新'尾巴'),但是元素p-> next是你的老尾巴。釋放後將指針設置爲空。 q-> tail的值已經指向'p',並且在這之後釋放'p'是無效的,因爲'p-> next'就是你想要刪除的內容。

可能就是這樣。

此外,我個人並不喜歡你如何將'Item'作爲void *放置在某處,它看起來很混亂,因爲'Item'看起來像是一個通過值傳遞的變量。

Kev

0

在我看來,你是釋放p,但在此之前,你指定的p價值q->tail離開q->tail指向即將是無效的內存。你實際上釋放了q->tail

其他地方我懷疑你使用q->tail這會讓你的操作系統尖叫並殺死你的程序,就像滑板上的Hades一樣。

2

問題是你點的東西,你會在接下來的代碼行釋放:

q->tail=p; 
... 
free((void *) p); 
現在

當你嘗試訪問Q->尾你會得到一個錯誤,因爲你已經釋放了這個記憶。

你應該嘗試免費的p>未來,而不是P(因爲P->接下來就是隊列中的最後一個項目 - 所以這是你要拿出一個)

好運:)