C++中将链表头指针赋值给同类型指针时出现段错误求助
链表头指针赋值时出现段错误的排查与修复
问题场景
将链表的struct头指针赋值给同类型临时指针时触发Segmentation fault(段错误),代码运行于在线C++编译器,代码如下:
#include <iostream> using namespace std; struct Node{ int val; Node *next; }; Node* newNode(int val){ Node *newNode = new Node; newNode->val = val; newNode->next = nullptr; return newNode; } Node* addNode(Node *head, int val){ if(head == nullptr){ return newNode(val); } Node *current = head; while(current->next != nullptr){ current = current->next; } current->next = newNode(val); return head; } void printList(Node *head){ while(head){ cout<<head->val<<" "; head = head->next; } cout<<endl; } int main() { Node *head; head = addNode(head, 1); head = addNode(head, 2); head = addNode(head, 3); head = addNode(head, 4); head = addNode(head, 5); head = addNode(head, 6); head = addNode(head, 7); printList(head); //If comment out, then no segmentation fault Node *head1 = head; //Segmentation fault return 0; }
问题根源
main函数中Node *head;定义了一个未初始化的野指针,其指向的内存地址是随机的。第一次调用addNode(head, 1)时,head的随机值大概率不等于nullptr,导致跳过if(head == nullptr)的分支,直接执行current = head; while(current->next != nullptr)——此时访问野指针的next成员属于非法内存操作,已经触发了未定义行为。
未定义行为的表现具有随机性,可能在printList调用时没有立刻崩溃,但执行Node *head1 = head;时,非法内存访问的影响最终显现为段错误。
修复方案
将main函数中的头指针初始化为nullptr:
int main() { Node *head = nullptr; // 初始化指针为nullptr head = addNode(head, 1); head = addNode(head, 2); head = addNode(head, 3); head = addNode(head, 4); head = addNode(head, 5); head = addNode(head, 6); head = addNode(head, 7); printList(head); Node *head1 = head; // 正常执行无段错误 return 0; }
修复原理
初始化head为nullptr后,第一次调用addNode会正确进入创建新节点的分支,返回合法的链表头指针。后续所有addNode和printList操作都基于合法指针,不会出现非法内存访问,赋值Node *head1 = head;也能正常执行。
内容的提问来源于stack exchange,提问作者Ankush S
相关产品推荐
相关产品推荐

