[英]Why does freeing the memory lead to segmentation fault?
我很絕望,因為這段代碼不時給我一個分段錯誤,我不知道為什么。 實際上它只是應該添加一些鏈表注釋,打印它們然后通過釋放 memory 來清空列表。
struct int_list {
int value;
struct int_list *next;
};
typedef struct int_list IntList;
void list_print(IntList *start)
{
IntList *cur = start;
while(cur != NULL)
{
printf("%d\n", cur->value);
cur = cur->next;
}
}
void list_append(IntList **start, int newval)
{
IntList *newel = malloc(sizeof(IntList));
newel->value = newval;
newel->next = NULL;
if(*start == NULL)
{
*start = newel;
}
else
{
IntList *cur = *start;
while(cur->next != NULL)
{
cur = cur->next;
}
cur->next = newel;
}
}
void list_free(IntList *start)
{
IntList *prev = start; // prev = start
while (start != NULL) // if start != Null
{
start = start->next; // make start point to the next element
printf("Deleting %d\n", prev->value);
free(prev); // delete the previous element
prev = start; // make previous point to start again
}
printf("\n");
}
int main(int argc, char *argv[])
{
// fill the list
IntList *start = NULL;
list_append(&start, 42);
list_append(&start, 30);
list_append(&start, 16);
// print the list
printf("\nList 1\n");
list_print(start);
printf("\n");
// free the memory and print again
list_free(start);
printf("Empty list:\n");
list_print(start);
printf("\n");
}
在我嘗試實現 list_free() 之前,一切正常。 所以我強烈假設錯誤可以在這個 function 中找到。 只需發布代碼的 rest,因為我是結構新手,並且不能 100% 確定是否正確處理它們。 你知道我做錯了什么嗎?...
由於懸空指針,您有未定義的行為
list_free(start);
也就是說, start
仍然指向您嘗試訪問的已釋放 memory 。
您需要在free
之后將start
設置為NULL
。
list_free(start);
start = NULL;
printf("Empty list:\n");
list_print(start);
function list_free
按值獲取其參數。 因此 function 處理指向節點的原始指針的副本。 結果,指向節點start
的原始指針保持不變。
因此,在調用 function list_free 之后,列表的list_free
list_free(start);
printf("Empty list:\n");
list_print(start);
具有未定義的行為。
function 應該像 function list_append
那樣通過引用接受指向節點的原始指針。
例如
void list_free( IntList **start )
{
while ( *start != NULL )
{
IntList *prev = *start; // prev = start
*start = ( *start )->next; // make start point to the next element
printf("Deleting %d\n", prev->value);
free(prev); // delete the previous element
}
printf("\n");
}
像這樣調用 function
list_free( &start );
退出 function 后,原始指針start
將等於NULL
。 那就是列表確實會被釋放。
這比列表的客戶端自己顯式設置指向NULL
的指針要好。 他可能會犯與您忘記將指針設置為 NULL 相同的錯誤。
指針仍然指向已釋放的 memory 的 memory 位置,這也是分段錯誤的一個實例。 這是“未定義的行為”,並且可能導致任意不可預測的事情發生,因為指向位置的內容是未知的,運行時間不同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.