什么导致双向链表代码中的段错误
What causes the segmentation fault in the doubly linked list code
调用 printList 时,以下代码会导致分段错误。这是为什么?
失败的工作示例位于 https://ide.geeksforgeeks.org/ZeqrQf9esb
#include <iostream>
struct Node {
int data;
Node * next;
Node * prev;
};
void addNode(struct Node **head_ref,int pos,int data)
{
struct Node*nn=new Node;
int k=0;
nn->data=data;
if(*head_ref==nullptr)
*head_ref=nn;
else
{
struct Node*temp=*head_ref;
while(k<pos)
{
temp=temp->next;
}
if(temp->next!=nullptr)
{
nn->prev=temp;
nn->next=temp->next;
temp->next=nn;
nn->next->prev=nn;
}
else
{
nn->next=nullptr;
nn->prev=temp;
temp->next=nn;
}
}
}
void printList(struct Node *Node)
{
struct Node *temp=Node;
//goto end
while(temp->next!=NULL)
{
temp=temp->next;
}
//goto start
while(temp->prev!=NULL)
{
temp = temp->prev;
}
//now print
while(temp!=NULL)
{
printf("%d ",temp->data);
temp=temp->next;
}
}
int main()
{
Node * head;
addNode(&head,0,10);
addNode(&head,0,11);
addNode(&head,0,12);
std::cerr << head->data << std::endl;
std::cerr << head->next->data << std::endl;
std::cerr << head->next->next-> data << std::endl;
printList(head);
}
1) 不要在同一代码中混用 malloc 和 new。您将忘记哪些节点来自哪个分配器,如果您释放来自 new 的某些内容,或删除来自 malloc 的某些内容,您就会遇到严重的错误。
2) 在前进 "k" 次时...您忘记增加 k 所以永远不要停止前进,然后离开您的列表。这是崩溃的根源:
while(k<pos)
{
temp=temp->next;
}
可能还有更多,但是看到#2我就不看了。
修复方法是将 next 和 prev 初始化为 null。如果您不这样做,那么它们将采用随机值。重要的行是
struct Node {
int data;
Node * next=nullptr;
Node * prev=nullptr;
};
有关工作示例,请参阅 https://wandbox.org/permlink/qooehizoRifrvOVX。完整代码如下
#include <iostream>
struct Node {
int data;
Node * next=nullptr;
Node * prev=nullptr;
};
void addNode(struct Node **head_ref,int pos,int data)
{
struct Node*nn=new Node;
int k=0;
nn->data=data;
if(*head_ref==nullptr)
*head_ref=nn;
else
{
struct Node*temp=*head_ref;
while(k<pos)
{
temp=temp->next;
}
if(temp->next!=nullptr)
{
nn->prev=temp;
nn->next=temp->next;
temp->next=nn;
nn->next->prev=nn;
}
else
{
nn->next=nullptr;
nn->prev=temp;
temp->next=nn;
}
}
}
void printList(struct Node *Node)
{
struct Node *temp=Node;
//goto end
while(temp->next!=nullptr)
{
temp=temp->next;
}
//goto start
while(temp->prev!=nullptr)
{
temp = temp->prev;
}
//now print
while(temp!=nullptr)
{
printf("%d ",temp->data);
temp=temp->next;
}
}
int main()
{
Node * head;
addNode(&head,0,10);
addNode(&head,0,11);
addNode(&head,0,12);
std::cerr << head->data << std::endl;
std::cerr << head->next->data << std::endl;
std::cerr << head->next->next-> data << std::endl;
printList(head);
}
调用 printList 时,以下代码会导致分段错误。这是为什么?
失败的工作示例位于 https://ide.geeksforgeeks.org/ZeqrQf9esb
#include <iostream>
struct Node {
int data;
Node * next;
Node * prev;
};
void addNode(struct Node **head_ref,int pos,int data)
{
struct Node*nn=new Node;
int k=0;
nn->data=data;
if(*head_ref==nullptr)
*head_ref=nn;
else
{
struct Node*temp=*head_ref;
while(k<pos)
{
temp=temp->next;
}
if(temp->next!=nullptr)
{
nn->prev=temp;
nn->next=temp->next;
temp->next=nn;
nn->next->prev=nn;
}
else
{
nn->next=nullptr;
nn->prev=temp;
temp->next=nn;
}
}
}
void printList(struct Node *Node)
{
struct Node *temp=Node;
//goto end
while(temp->next!=NULL)
{
temp=temp->next;
}
//goto start
while(temp->prev!=NULL)
{
temp = temp->prev;
}
//now print
while(temp!=NULL)
{
printf("%d ",temp->data);
temp=temp->next;
}
}
int main()
{
Node * head;
addNode(&head,0,10);
addNode(&head,0,11);
addNode(&head,0,12);
std::cerr << head->data << std::endl;
std::cerr << head->next->data << std::endl;
std::cerr << head->next->next-> data << std::endl;
printList(head);
}
1) 不要在同一代码中混用 malloc 和 new。您将忘记哪些节点来自哪个分配器,如果您释放来自 new 的某些内容,或删除来自 malloc 的某些内容,您就会遇到严重的错误。
2) 在前进 "k" 次时...您忘记增加 k 所以永远不要停止前进,然后离开您的列表。这是崩溃的根源:
while(k<pos)
{
temp=temp->next;
}
可能还有更多,但是看到#2我就不看了。
修复方法是将 next 和 prev 初始化为 null。如果您不这样做,那么它们将采用随机值。重要的行是
struct Node {
int data;
Node * next=nullptr;
Node * prev=nullptr;
};
有关工作示例,请参阅 https://wandbox.org/permlink/qooehizoRifrvOVX。完整代码如下
#include <iostream>
struct Node {
int data;
Node * next=nullptr;
Node * prev=nullptr;
};
void addNode(struct Node **head_ref,int pos,int data)
{
struct Node*nn=new Node;
int k=0;
nn->data=data;
if(*head_ref==nullptr)
*head_ref=nn;
else
{
struct Node*temp=*head_ref;
while(k<pos)
{
temp=temp->next;
}
if(temp->next!=nullptr)
{
nn->prev=temp;
nn->next=temp->next;
temp->next=nn;
nn->next->prev=nn;
}
else
{
nn->next=nullptr;
nn->prev=temp;
temp->next=nn;
}
}
}
void printList(struct Node *Node)
{
struct Node *temp=Node;
//goto end
while(temp->next!=nullptr)
{
temp=temp->next;
}
//goto start
while(temp->prev!=nullptr)
{
temp = temp->prev;
}
//now print
while(temp!=nullptr)
{
printf("%d ",temp->data);
temp=temp->next;
}
}
int main()
{
Node * head;
addNode(&head,0,10);
addNode(&head,0,11);
addNode(&head,0,12);
std::cerr << head->data << std::endl;
std::cerr << head->next->data << std::endl;
std::cerr << head->next->next-> data << std::endl;
printList(head);
}