C++链表实现拷贝构造函数触发读访问错误问题排查
问题1:DeleteList方法存在致命逻辑错误
你当前DeleteList中的代码逻辑完全无效:
temp->data = nullptr; delete temp->data;
你先把data指针置为空,再delete空指针没有任何实际释放作用,原本data指向的堆内存会直接泄漏。
你之前直接delete temp->data报错的原因是Node创建时没有对data指针做初始化,未初始化的指针是野指针,直接delete野指针必然触发断言错误。正确的处理逻辑是Node构造时就把data和next都初始化为nullptr,释放时只有确认data指向有效堆内存再执行delete。
正确的DeleteList写法:
void DeleteList() { Node<T>* temp; while (head_ != nullptr) { temp = head_; head_ = head_->next; // 仅非空指针执行释放 if (temp->data != nullptr) { delete temp->data; } delete temp; } }
同时需要给Node补充默认构造函数,避免野指针:
template <class T> struct Node { T* data; Node* next; // 新增默认构造,初始化成员为nullptr Node() : data(nullptr), next(nullptr) {} // 可选:带参数构造,创建节点时直接完成内存分配和值拷贝 Node(const T& val) : next(nullptr) { data = new T(val); } };
问题2:拷贝赋值运算符为浅拷贝,直接触发访问冲突
你当前的拷贝赋值逻辑是直接复制源节点的data指针d_node->data = (source.head_)->data,这会导致两个链表的节点指向同一块T类型的内存。当任意一方链表被销毁,DeleteList会释放这块内存,另一方的data就变成野指针,访问时就会抛出读访问冲突,这是你报错的根本原因。
拷贝时需要做深拷贝,给目标节点的data单独分配堆内存、复制值而不是复制指针,正确的拷贝赋值调整如下:
List342& operator=(const List342& source) { if (this == &source) { return *this; } DeleteList(); if (source.head_ == nullptr) { return *this; } Node<T>* s_node = source.head_; // 头节点深拷贝 head_ = new Node<T>(*(s_node->data)); Node<T>* d_node = head_; s_node = s_node->next; while (s_node != nullptr) { d_node->next = new Node<T>(*(s_node->data)); d_node = d_node->next; s_node = s_node->next; } return *this; }
如果不准备给Node加带参构造,也可以手动分配内存完成拷贝:
d_node->data = new T(*(s_node->data));
调整后两个链表的data指针指向独立内存,不会出现释放后访问的冲突。
内容的提问来源于stack exchange,提问作者DerpyDays
相关产品推荐
相关产品推荐

