C++单链表创建报错求助:EXC_BAD_ACCESS问题排查
C++单向链表空指针访问错误排查与解决
核心错误点分析
- 空指针解引用:
IntLinkedList构造函数把head初始化为nullptr,add方法里直接执行*head = IntNode(...),这是在访问地址0的无效内存,直接触发EXC_BAD_ACCESS错误。C++里指针必须先通过new分配有效内存才能解引用操作。 - 节点链接方法设计错误:
IntNode::getLink()返回的是对象副本,不是指针,导致无法正确修改链表的节点链接关系,后续操作全无效。 - 尾插逻辑错误:原
add方法的else分支完全搞错了尾插的逻辑,没有正确创建新节点并更新链表尾部的指向。
修正后的代码实现
IntNode.hpp
修改getLink的返回类型为指针,确保能正确操作节点链接:
#ifndef IntNode_h #define IntNode_h class IntNode { private: int data; IntNode *link; public: IntNode(int newData, IntNode *newLink); int getData(); IntNode* getLink(); // 改为返回指针 void setData(int newData); void setLink(IntNode *newLink); }; #endif /* IntNode_h */
IntNode.cpp
对应更新getLink的实现:
#include <stdio.h> #include "IntNode.hpp" IntNode::IntNode(int newData, IntNode *newLink) { data = newData; link = newLink; } int IntNode::getData() { return data; } IntNode* IntNode::getLink() { return link; } void IntNode::setData(int newData) { data = newData; } void IntNode::setLink(IntNode *newLink) { link = newLink; }
IntLinkedList.cpp
重写add方法,正确处理空链表和尾插逻辑,先分配内存再操作指针:
#include<iostream> #include "IntLinkedList.hpp" #include "IntNode.hpp" IntLinkedList::IntLinkedList() { head = nullptr; tail = nullptr; numElements = 0; } void IntLinkedList::add(int newElement) { // 先为新节点分配动态内存 IntNode* newNode = new IntNode(newElement, nullptr); if (head == nullptr) { // 链表为空时,首尾指针都指向新节点 head = newNode; tail = newNode; } else { // 尾插:把当前尾节点的link指向新节点,再更新tail到新节点 tail->setLink(newNode); tail = newNode; } numElements++; } // 补充析构函数,避免内存泄漏 IntLinkedList::~IntLinkedList() { IntNode* current = head; while (current != nullptr) { IntNode* nextNode = current->getLink(); delete current; current = nextNode; } head = nullptr; tail = nullptr; numElements = 0; }
IntLinkedList.hpp
补充析构函数声明:
#ifndef IntLinkedList_hpp #define IntLinkedList_hpp #include <stdio.h> #include "IntNode.hpp" class IntLinkedList { private: IntNode *head; IntNode *tail; int numElements; public: IntLinkedList(); ~IntLinkedList(); // 添加析构函数声明 void add(int newElement); }; #endif /* IntLinkedList_hpp */
额外说明
作为Java转C的开发者,要注意C没有自动垃圾回收,动态分配的内存(用new创建的对象)必须手动用delete释放,否则会造成内存泄漏。上面添加的析构函数就是用来在链表对象销毁时清理所有节点内存的。
内容的提问来源于stack exchange,提问作者J R
相关产品推荐
相关产品推荐

