C++实现单链表时访问引用指针出现访问违规错误的原因是什么
问题产生的核心原因
- 存在未定义行为:返回局部变量的引用
你的getNode函数返回值是Node<T>*&即指针的左值引用,但函数内用到的p和边界判断里的temp都是栈上的局部变量,函数执行结束后栈空间会被回收,返回的引用属于悬空引用,后续访问该引用会直接触发内存访问错误。 - 成员变量
size未初始化
构造函数仅初始化了head,size是随机垃圾值,导致getNode中k > size的边界判断完全失效。你在main函数中总共插入了5个元素,合法索引范围为0~4,调用getNode(5)本应触发边界判断返回空,但是因为size是垃圾值,判断失效后会导致指针越界访问。 addNode插入头节点逻辑错误
非空链表插入头节点时,你的代码写的是newNode->next = head->next; head = newNode;,会直接丢失原来的头节点,正确逻辑应为newNode->next = head;。- 析构函数逻辑错误
链表为空时直接访问head->next会触发段错误,且循环条件head->next != nullptr会导致最后一个节点无法被释放,存在内存泄漏。 deleteNode尾节点处理逻辑错误
尾节点的next本身就是nullptr,执行delete n->next没有任何意义,且仅将参数n设为nullptr完全不会修改链表中前驱节点的next指针,会导致链表断裂、出现野指针。- 存在不必要的内存泄漏
getNode中Node<T>* p = new Node<T>;之后马上给p赋值为head,new出来的节点完全没有被使用就丢失了指针,造成内存泄漏。
关于getNode是否可以返回p指针的问题
你当前的写法里不能返回p的引用,属于标准未定义行为。如果把返回值类型修改为Node<T>*(返回指针的值,不是指针的引用),是可以正常返回p的,不会有悬空引用问题。
核心代码修正示例
// 修正getNode返回值为指针而非引用,调整边界判断和循环逻辑 Node<T>* getNode(int k)const { if (head == nullptr || k <0 || k >= size) { return nullptr; } Node<T>* p = head; for (int i = 0; i < k && p != nullptr; i++) { p = p->next; } return p; } // 构造函数补充size初始化 SingleLList() :head(nullptr),size(0) {}; // 修正析构函数逻辑 ~SingleLList() { Node<T>* delNode; while (head != nullptr) { delNode = head; head = head->next; delete delNode; } } // 修正头插逻辑 if (index == 0) { newNode->next = head; head = newNode; size++; }
内容的提问来源于stack exchange,提问作者JIK
相关产品推荐
相关产品推荐

