调试链表指针代码:分段错误



所以下面的代码:

/*
* For your reference:
*
* SinglyLinkedListNode {
*     int data;
*     SinglyLinkedListNode* next;
* };
*
*/
SinglyLinkedListNode* insertNodeAtTail(SinglyLinkedListNode* head, int data) {
SinglyLinkedListNode* temp = head;
while (temp != NULL) {
temp = temp->next;
}
SinglyLinkedListNode* temp1;
temp1->data = data;
temp1->next = NULL;
temp->next = temp1;
return temp;
}

所以,基本上我想在链接列表"head"的末尾添加"data",并返回更新后的列表。那么问题出在哪里呢?

编辑:好吧,我犯了第一个错误。但即使我换了临时工=NULL,temp->next=循环中的NULL条件仍然存在此错误

您必须为节点分配内存。记得清理分配的内存。对于每次呼叫new,您都需要一个呼叫delete。因此,我更喜欢智能指针。

在循环之后,temp包含NULL。不能取消引用空指针。

SinglyLinkedListNode* insertNodeAtTail(SinglyLinkedListNode* head, int data) {
SinglyLinkedListNode* temp1 = new SinglyLinkedListNode;
temp1->data = data;
temp1->next = nullptr;
if (!head) {
head = temp1;
return head;
}
SinglyLinkedListNode* temp = head;
while(temp->next){
temp = temp->next;
}
temp->next = temp1;
return temp;
}

此函数

SinglyLinkedListNode* insertNodeAtTail(SinglyLinkedListNode* head, int data) {
SinglyLinkedListNode* temp=head;
while(temp!=NULL){
temp=temp->next;
}
SinglyLinkedListNode* temp1;
temp1->data=data;
temp1->next=NULL;
temp->next=temp1;
return temp;
}

没有道理。在这个循环之后

while(temp!=NULL){
temp=temp->next;
}

指针CCD_ 5等于NULL。所以这个声明

temp->next=temp1;

调用未定义的行为。

指针temp1未初始化。所以再次这些陈述

temp1->data=data;
temp1->next=NULL;

调用未定义的行为。

函数的用户不知道返回的指针是列表的头指针还是最后一个指针。因此,不清楚是将返回的指针分配给头指针,还是忽略返回的值。

该函数的外观如下。

void insertNodeAtTail( SinglyLinkedListNode * &head, int data ) 
{
SinglyLinkedListNode **current = &head;
while ( *current != nullptr ) current = &( *current )->next;
*current = new SinglyLinkedListNode { data, nullptr };
}

如果你主要定义了指向头节点的指针,比如

SinglyLinkedListNode *head = nullptr;

那么函数调用将看起来像

insertNodeAtTail( head, some_data );

该函数的另一个定义可以如下

SinglyLinkedListNode* insertNodeAtTail( SinglyLinkedListNode *head, int data ) 
{
SinglyLinkedListNode *new_node = new SinglyLinkedListNode { data, nullptr };
if ( head == nullptr )
{
head = new_node;
}
else
{
SinglyLinkedListNode *current = head;
while ( current->next != nullptr ) current = current->next;
current->next = new_node;
}
return head;
}

在这种情况下,如果你主要定义了指向头节点的指针,比如

SinglyLinkedListNode *head = nullptr;

那么函数调用将看起来像

head = insertNodeAtTail( head, some_data );

在这两个函数定义之间,第一个函数定义是优选的,因为不需要记住将返回的指针分配给头节点。

请记住,如果您有一个单链列表,并且希望将新节点附加到列表的尾部,那么最好定义双侧单链列表。在这种情况下,列表定义可能看起来像

class SinglyLinkedList
{
private:
struct Node
{
int data,
Node *next;
} *head = nullptr, *tail = nullptr;
public:
SinglyLinkedList() = default;
void insertNodeAtHead( int data );
void insertNodeAtTail( int data );
// other member functions;
};

它也在这里崩溃:

SinglyLinkedListNode* temp1;
temp1->data=data;

当到达循环while(temp!=NULL){的末尾时,这里的temp就是NULL。下面您使用的语句类似于temp->next=temp1;,这会导致崩溃

最新更新