在 LinkedList 中插入一个节点会产生分段错误
Inserting a node in LinkedList is giving segmentation error
struct Node
{
int data;
Node * next;
Node (int x)
{
data=x;
next=NULL;
}
};
Node * insertInSorted(Node * head, int data)
{
Node* temp = new Node(data);
if (head == NULL){
return temp;
}
if (data < head->data){
temp->next = head
return temp;
}
Node* curr = head;
while (curr->next->data < data && curr->next != NULL){
curr = curr->next;
}
temp->next = curr->next;
curr->next = temp;
return head;
}
你好,我最近学了C++,一直在练习LinkedList,这道题很简单,我要做的就是在正确的位置插入一个元素,同时保持排序。
我的问题是为什么我会出现分段错误。我注意到在 while 循环中,如果我从 while (curr->next->data < data && curr->next != NULL) to while (curr->next != NULL && curr->next->data < data)不会出现分段错误。有人可以帮我理解这个问题吗?
你写的方式,这个:
curr->next->data < data
在此之前评价:
curr->next != NULL
因此,当您尝试在 curr->next->data
中取消引用它时,curr->next
可能为 NULL,因此您访问了内存的某个随机部分并出现了分段错误。
正如您所说,更改顺序即可解决问题,这是正确的解决方案。当 AND
表达式的第一部分为 false 时,不会计算第二部分,因此您不会尝试取消引用无效地址,因此您的问题已解决。
这个while循环
while (curr->next->data < data && curr->next != NULL){
curr = curr->next;
}
可以调用未定义的行为,因为在访问数据成员 curr->next->data
之前没有检查 curr->next
是否等于 nullptr
。您需要交换逻辑 AND 运算符的操作数,如
while (curr->next != NULL && curr->next->data < data ){
curr = curr->next;
}
在任何情况下,如果使用指向指针的指针,都可以在不检查大量条件的情况下按以下方式编写函数。
Node * insertInSorted( Node *head, int data )
{
Node *temp = new Node( data );
Node **current = &head;
while ( *current && !( data < ( *current )->data ) )
{
current = &( *current )->next;
}
temp->next = *current;
*current = temp;
return head;
}
注意可以通过引用将指向头节点的指针传递给函数。在这种情况下,不需要 return 从函数指向头节点的指针。原始函数的用户可能忘记将函数的 returned 指针分配给函数调用者中的指针。
所以更安全的函数定义可以看下面的方式
void insertInSorted( Node * &head, int data )
{
Node *temp = new Node( data );
Node **current = &head;
while ( *current && !( data < ( *current )->data ) )
{
current = &( *current )->next;
}
temp->next = *current;
*current = temp;
}
struct Node
{
int data;
Node * next;
Node (int x)
{
data=x;
next=NULL;
}
};
Node * insertInSorted(Node * head, int data)
{
Node* temp = new Node(data);
if (head == NULL){
return temp;
}
if (data < head->data){
temp->next = head
return temp;
}
Node* curr = head;
while (curr->next->data < data && curr->next != NULL){
curr = curr->next;
}
temp->next = curr->next;
curr->next = temp;
return head;
}
你好,我最近学了C++,一直在练习LinkedList,这道题很简单,我要做的就是在正确的位置插入一个元素,同时保持排序。 我的问题是为什么我会出现分段错误。我注意到在 while 循环中,如果我从 while (curr->next->data < data && curr->next != NULL) to while (curr->next != NULL && curr->next->data < data)不会出现分段错误。有人可以帮我理解这个问题吗?
你写的方式,这个:
curr->next->data < data
在此之前评价:
curr->next != NULL
因此,当您尝试在 curr->next->data
中取消引用它时,curr->next
可能为 NULL,因此您访问了内存的某个随机部分并出现了分段错误。
正如您所说,更改顺序即可解决问题,这是正确的解决方案。当 AND
表达式的第一部分为 false 时,不会计算第二部分,因此您不会尝试取消引用无效地址,因此您的问题已解决。
这个while循环
while (curr->next->data < data && curr->next != NULL){
curr = curr->next;
}
可以调用未定义的行为,因为在访问数据成员 curr->next->data
之前没有检查 curr->next
是否等于 nullptr
。您需要交换逻辑 AND 运算符的操作数,如
while (curr->next != NULL && curr->next->data < data ){
curr = curr->next;
}
在任何情况下,如果使用指向指针的指针,都可以在不检查大量条件的情况下按以下方式编写函数。
Node * insertInSorted( Node *head, int data )
{
Node *temp = new Node( data );
Node **current = &head;
while ( *current && !( data < ( *current )->data ) )
{
current = &( *current )->next;
}
temp->next = *current;
*current = temp;
return head;
}
注意可以通过引用将指向头节点的指针传递给函数。在这种情况下,不需要 return 从函数指向头节点的指针。原始函数的用户可能忘记将函数的 returned 指针分配给函数调用者中的指针。
所以更安全的函数定义可以看下面的方式
void insertInSorted( Node * &head, int data )
{
Node *temp = new Node( data );
Node **current = &head;
while ( *current && !( data < ( *current )->data ) )
{
current = &( *current )->next;
}
temp->next = *current;
*current = temp;
}