我正在實作一個回圈鏈表,并試圖創建將釋放鏈表和鏈表中節點的函式。我有一個LL_t指向鏈表頭部和尾部的型別。然后是LL_node_t節點的鏈表。
我已盡力獲取代碼的重要部分以及我正在處理的輸出,以更好地展示我的問題。
我的問題是,為什么在我temp_llnode_ptr開始時使用這個 value temp_llnode_ptr: 0x7fffcf9c7310,但在呼叫我的 free 函式后以NEW temp_llnode_ptr: 0x7fffcf9c6010. 它以我的第二個節點的地址開始。我嘗試釋放我的第一個節點。然后在函式之后 mytemp_llnode_ptr具有不同的值。
void
free_LL (LL_t** list)
{
LL_node_t** temp_llnode_ptr = NULL;
for (int i = 0; i < (*list)->LL_length; i )
{
printf("Inside FOR loop\n");
printf("list->head: %p\n", (void*)(*list)->head);
printf("list->tail: %p\n", (void*)(*list)->tail);
temp_llnode_ptr = &(*list)->head->next;
printf("temp_llnode_ptr: %p\n", (void*)(*temp_llnode_ptr));
printf("(*temp_llnode_ptr)->next: %p\n", (void*)(*temp_llnode_ptr)->next);
free_LL_node(&(*list)->head);
printf("NEW temp_llnode_ptr: %p\n", (void*)(*temp_llnode_ptr));
printf("NEW list->head: %p\n", (void*)(*list)->head);
}
}
void
free_LL_node (LL_node_t** node)
{
(*node)->next = NULL;
(*node)->data = NULL;
printf("node about to be FREED is: %p\n", (void*)(*node));
free(*node);
*node = NULL;
}
OUTPUT FROM PRINT FUNC (The nodes in my linked list)
Node#: 0 | Current node: 0x7fffcf9c72f0 | Node data: 10 | Next node 0x7fffcf9c7310
Node#: 1 | Current node: 0x7fffcf9c7310 | Node data: 20 | Next node 0x7fffcf9c7330
Node#: 2 | Current node: 0x7fffcf9c7330 | Node data: 30 | Next node 0x7fffcf9c72f0
Inside FOR loop
list->head: 0x7fffcf9c72f0
list->tail: 0x7fffcf9c7330
temp_llnode_ptr: 0x7fffcf9c7310 <--- Why do these change?
(*temp_llnode_ptr)->next: 0x7fffcf9c7330
node about to be FREED is: 0x7fffcf9c72f0
NEW temp_llnode_ptr: 0x7fffcf9c6010 <--- Why do these change?
NEW list->head: (nil)
uj5u.com熱心網友回復:
讓X是(*list)->head指向的東西。然后temp_llnode_ptr設定為 的地址X->next。呼叫free_LL_node(&(*list)->head);的FreeS X。一旦X被釋放,其記憶體中的內容就不再可靠。除其他外,它們很可能已被記憶體管理例程更改,將記憶體用于其自身目的。X->next在那個記憶體中,所以它的內容可能已經改變了。列印(*temp_llnode_ptr)嘗試列印X->next.
由于temp_llnode_ptr指向一個已被釋放的物件,根據 C 標準,它的值是不確定的。(這是正確的,因為由C標準中規定的,之后free(p),該值的p不再是確定的,即使free不能改變用來保存存盤器p,在語意意義它的“價值”可以依賴于在存盤器中的其他資料,和該資料可能會被 更改p,因此其“值”不再確定。)此外,*temp_llnode_ptr嘗試使用該記憶體,并且 C 標準未定義其行為。
uj5u.com熱心網友回復:
讓我們看看有問題的部分:
temp_llnode_ptr = &(*list)->head->next;
printf("temp_llnode_ptr: %p\n", (void*)(*temp_llnode_ptr));
free_LL_node(&(*list)->head);
printf("NEW temp_llnode_ptr: %p\n", (void*)(*temp_llnode_ptr));
第一行設定temp_llnode_ptr為指向next第一個節點中的變數。
第二行查看該變數中的值(該值是第二個節點的地址)并列印它。
第三行釋放第一個節點。
第二行查看該變數中的值——該變數是第一個節點的一部分——我們剛剛釋放了它——并列印它。因為我們剛剛釋放了這個變數,所以我們不應該再使用它了。在這種情況下,看起來記憶體管理系統已經使用記憶體中的那個點來保存一些與記憶體管理相關的指標。這沒有什么關系,但-那不是你的問題-你的問題是,你不應該使用它在所有你釋放之后。
你似乎認為temp_llnode_ptr指向下一個節點。我認為這適合您的目的,所以您可以這樣做。temp_llnode_ptr可以只是一個指標(而不是指向指標的指標,也就是雙指標),然后你還有一堆額外的&s 和*s 需要洗掉。
如果你這樣做temp_llnode_ptr = (*list)->head->next;(洗掉一個&),那么 temp_llnode_ptr 將指向下一個節點(而不是指向next哪個指向下一個節點),你應該能夠自己解決其余的問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/338888.html
上一篇:列印降序陣列C
