我剛剛開始自學 C ,作為一個玩具問題,我正在嘗試執行以下操作 - 給定一個鏈表,我想將所有節點存盤到一個新串列中,并回傳這個新串列。對于背景關系,我來自 Python 背景。
我有以下程式 -
#include <iostream>
using namespace std;
struct node
{
unsigned val;
struct node *next;
};
node *even_nodes(node **root)
{
node *new_list_head = NULL;
node *new_list_runner = NULL;
node *runner = *root;
while (runner != NULL)
{
if (new_list_head != NULL){
printf("OUTSIDE LOOP new_list_head.val = %d\n", new_list_head->val);
}
if (runner->val % 2 == 0)
{
cout << runner->val << endl;
node new_node = {.val = runner->val, .next = NULL};
if (new_list_head == NULL)
{
printf("new_list_head is NULL!\n");
new_list_head = &new_node;
new_list_runner = &new_node;
printf("after allocation. new_list_head.val = %d\n", new_list_head->val);
}
else
{
printf("new_list_head is NOT NULL! new_list_head.val = %d\n", new_list_head->val);
new_list_runner->next = &new_node;
new_list_runner = new_list_runner->next;
printf("after allocation. new_list_head.val = %d\n", new_list_head->val);
}
}
runner = runner->next;
}
printf("new_list_head val = %d\n", new_list_head->val);
return new_list_head;
};
void add_data(node **root, int new_data)
{
node *new_node = (node *)malloc(sizeof(node *));
new_node->val = new_data;
new_node->next = (*root);
(*root) = new_node;
}
void print_list(node *root)
{
node *head = root;
while (head != NULL)
{
printf("%d -> ", head->val);
head = head->next;
}
printf("END\n");
};
int main()
{
node *head = NULL;
add_data(&head, 19);
add_data(&head, 18);
add_data(&head, 3);
add_data(&head, 4);
add_data(&head, 1);
printf("Initial list:\n");
print_list(head);
node *new_list = even_nodes(&head);
printf("New list of even numbers: \n");
print_list(new_list);
return 0;
}
輸出如下 -
Initial list:
1 -> 4 -> 3 -> 18 -> 19 -> END
4
new_list_head is NULL!
after allocation. new_list_head.val = 4
OUTSIDE LOOP new_list_head.val = 4
OUTSIDE LOOP new_list_head.val = 4
18
new_list_head is NOT NULL! new_list_head.val = 18
after allocation. new_list_head.val = 18
OUTSIDE LOOP new_list_head.val = 18
new_list_head val = 18
New list of even numbers:
[1] segmentation fault
我不明白為什么new_list_head也隨著改變new_list_runner?為什么我new_list_head指向新串列的最后一個元素,而不是第一個?
另外,為什么會出現段錯誤?方法中print_list,為什么是守衛
while (head != NULL)
不作業?
任何幫助將不勝感激!
uj5u.com熱心網友回復:
您不能通過獲取區域變數的地址來進行動態分配。當作用域退出時,區域變數被銷毀,你留下一個指向不存在的物件的指標(稱為懸空指標)。
你的代碼在這里有這個問題
node new_node = {.val = runner->val, .next = NULL}; // local variable
if (new_list_head == NULL)
{
new_list_head = &new_node; // BAD
new_list_runner = &new_node; // BAD
}
else
{
new_list_runner->next = &new_node; // BAD
new_list_runner = new_list_runner->next;
}
相反,您應該使用它new來分配新節點,使用它們創建的物件在new您使用它們之前不會被銷毀delete。
node* new_node = new node{runner->val, NULL};
if (new_list_head == NULL)
{
new_list_head = new_node;
new_list_runner = new_node;
}
else
{
new_list_runner->next = new_node;
new_list_runner = new_list_runner->next;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/537843.html
標籤:C 指针链表
上一篇:C 中指標的靜態優先級佇列
下一篇:求2個單鏈表的交集和并集
