c++ - 段错误:链表节点插入函数 [C++]
问题描述
我创建了一个名为“插入”的函数,用于在链接列表中插入一个新节点。它采用值和头节点进行插入。当我自己手动添加节点时,程序按预期运行,但是当我使用该函数添加节点时出现分段错误。
我可以通过一些小调整来使该函数工作,但还有一个问题,我失去了头节点作为指针的属性,它现在包含一些垃圾数据,当我打印 LinkedList 时会打印这些数据。
我执行的调整是:
Change Line 26 to: A->next = NULL;
Change Line 17 to: while(temp->next != NULL)
“分段错误”发生在第 20 行(未完成调整时):
Line 20 -----> temp->next = addTo;
我已经尝试通过引用传递参数,使用头节点的全局变量并检查函数的逻辑。该逻辑适用于手动添加节点。
我附上了下面的完整代码:
#include <bits/stdc++.h>
using namespace std;
struct ListNode {
int data;
ListNode *next;
};
void Insert(int x , ListNode* head)
{
ListNode* addTo = new ListNode();
addTo->data = x;
addTo->next = NULL;
ListNode* temp;
temp = head;
while(temp != NULL)
temp = temp->next;
temp->next = addTo;
}
int main()
{
ListNode* A;
A = NULL;
//Inserting A Node Manually
// ListNode* first = new ListNode();
// first->data = 9;
// first->next = NULL;
// while(A != NULL)
// A = A->next;
// A = first;
//Inserting using Insert function.
Insert(2,A);Insert(3,A);Insert(6,A);Insert(7,A);
//Printing
ListNode* temp = A;
while(temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
return 0;
}
我希望将节点添加到列表中,因为逻辑似乎是正确的,但是我遇到了分段错误。
对此的任何帮助/见解都会有很大帮助。
谢谢你。
解决方案
问题1:
while(temp != NULL)
temp = temp->next;
temp->next = addTo;
保证temp
将NULL
在while(temp != NULL)
退出时进行。这意味着没有temp
得到next
从。
与其在这里解决这个问题,我将继续解决问题 2,用一块石头杀死两只鸟。
问题2:
void Insert(int x , ListNode* head)
head
如果函数中发生更改,您将无法更新调用者Insert
。您可以更改 指向的对象head
,但head
它本身只是地址的副本。如果您将此副本更改为指向另一个地址,则调用者不知道。
这意味着你每次打电话Insert(<number>, A);
,A
都会一直在NULL
。
解决方案:
通过引用head
传入Insert
,以便可以对其进行更新。
void Insert(int x , ListNode*& head)
^ reference to pointer
head
的工作是指向列表中的第一项。这意味着它与任何next
指针做同样的事情:它指向下一项。唯一的区别是名称。我们可以通过添加一个额外的间接,一个指向head
.
ListNode ** temp = &head;
请注意,我们不能ListNode *& temp
在此处使用引用 (),因为一旦初始化引用以引用一个对象,就不能将其更改为引用不同的对象。您可以更改的指针,允许我们遍历列表并始终指向temp
下一个next
。
现在head
或任何next
是简单的temp
。这使得head
与所有其他变量完全相同,next
并且不需要特殊情况。
void Insert(int x , ListNode*& head)
{
ListNode* addTo = new ListNode();
addTo->data = x;
addTo->next = NULL; // consider making a smarter ListNode constructor that makes
// it impossible to forget to set next.
ListNode ** temp = &head; // we can now manipulate the address in head through temp
while(*temp != NULL) // note the dereference to get the pointed at pointer
// temp won't be null, but it could be pointing at a pointer
// that is null, and that is the end of the list
{ // I always use the optional braces. They prevent confusion.
temp = &(*temp)->next; //get pointer to the next next pointer
// we can now manipulate it exactly the same as head.
}
// we exit the loop with a pointer to the next pointer that we wish to point at
// the new list item regardless of whether it's head or the next of some later
// link in the list
*temp = addTo; // update the pointed at pointer with the new Node.
}
社区添加的第一个答案如何在 C++ 中正确删除链表的节点演示了如何使用相同的指针对指针技巧来轻松删除节点。
推荐阅读
- kubernetes - 无法在 Kubernetes 集群中安装 Istio
- .net - 卸载 .NET framework 4.7 并在 Azure 机器上安装 4.5
- javascript - 如何在 Django 模板中使用 JavaScript?
- python - 如何正确地将数组从 Django/Python 传递到 Postgres/PLPGSQL 存储的 proc 可变参数
- javascript - 将 HTML 元素的 innerText 复制到剪贴板
- linux - `execve()` 是否设置寄存器来调用动态链接器或要执行的可执行文件?
- command-line-interface - 术语 'OC_EDITOR="subl" 未被识别为 cmdlet、函数、脚本文件或可运行程序的名称
- python - PyTorch weak_script_method 装饰器
- java - 未找到 Intellij JavaFX helloWorld 模块
- javascript - 在新窗口中打开一个 src 脚本