C++泛型链表类方法异常:传入值失效,返回随机值
泛型链表head()返回随机值问题排查
核心错误原因
代码里的致命问题是在append方法中创建了栈上的局部Node对象:
auto next = Node<A>{.val = a, .next = nullptr};
当append函数执行完毕后,栈上的next会被销毁,内存被系统回收。但你把&next赋值给了first或last指针,这些指针直接变成野指针。后续调用head()访问已释放的内存,得到的自然是随机垃圾值。
修正方案
必须在堆上创建Node对象,用new分配内存,确保对象在链表生命周期内持续存在:
修正后的append方法
template<typename A> void LinkedList<A>::append(A a) { std::cout << "adding "; std::cout << a << std::endl; // 用new在堆上创建Node,避免函数结束后内存被释放 auto next = new Node<A>{.val = a, .next = nullptr}; std::cout << next->val << std::endl; if (this->last) { this->last->next = next; this->last = this->last->next; } else if (this->first) { this->last = next; this->first->next = next; } else { std::cout << "setting first" << std::endl; this->first = next; this->last = next; // 原代码遗漏了第一个元素时last的初始化,补上 std::cout << this->first->val << std::endl; } }
额外注意事项
- 原代码中类成员
first和last未初始化,默认是野指针,建议在类定义时直接初始化为nullptr:
Node<A>* first = nullptr; Node<A>* last = nullptr;
- 因为用了
new分配内存,必须添加析构函数释放所有节点内存,避免内存泄漏:
template<typename A> LinkedList<A>::~LinkedList() { Node<A>* current = first; while (current != nullptr) { Node<A>* next = current->next; delete current; current = next; } }
main.cpp里的ll->append(a);中a未定义,需要替换为具体值,比如ll->append(10);。
修正后的完整代码示例
// generic_linked_list.h namespace generic_linked_list { template<typename A> struct Node { A val; Node<A>* next; }; template<typename A> class LinkedList { public: Node<A>* first = nullptr; Node<A>* last = nullptr; void append(A a); A* head(); A* tail(); ~LinkedList(); }; } #include "generic_linked_list.h" #include <iostream> namespace generic_linked_list { template<typename A> void LinkedList<A>::append(A a) { std::cout << "adding "; std::cout << a << std::endl; auto next = new Node<A>{.val = a, .next = nullptr}; std::cout << next->val << std::endl; if (this->last) { this->last->next = next; this->last = this->last->next; } else if (this->first) { this->last = next; this->first->next = next; } else { std::cout << "setting first" << std::endl; this->first = next; this->last = next; std::cout << this->first->val << std::endl; } } template<typename A> A* LinkedList<A>::head() { if (this->first) { std::cout << "getting "; std::cout << this->first->val << std::endl; return &this->first->val; } return nullptr; }; template<typename A> A* LinkedList<A>::tail() { if (this->last) return &this->last->val; return nullptr; }; template<typename A> LinkedList<A>::~LinkedList() { Node<A>* current = first; while (current != nullptr) { Node<A>* next = current->next; delete current; current = next; } } } // main.cpp int main() { generic_linked_list::LinkedList<int>* ll = new generic_linked_list::LinkedList<int>(); ll->append(10); std::cout << *ll->head() << std::endl; delete ll; return 0; }
内容的提问来源于stack exchange,提问作者user3751379
相关产品推荐
相关产品推荐

