C++链表查询异常:InvoiceDetails节点共享致查询结果数据混乱
问题分析与修复
问题根源
你的findByInvoiceId方法直接将原链表中的节点添加到结果链表中,而add函数会修改节点的next指针。这会破坏原链表的节点连接关系:当你把原节点加入结果链表时,原节点的next会被覆盖为结果链表的下一个节点,导致原链表的结构被篡改,后续查询其他发票ID时,就会出现错误条目混杂的情况。
修复代码
1. 调整add函数,支持添加数据副本
修改后的add函数会为传入的数据创建新节点,避免修改原链表的节点:
template <typename T> void add(List<T> &list, const T &data) { Node<T> *newNode = new Node<T>(); newNode->data = data; newNode->next = NULL; if (list.head == NULL) { list.head = newNode; list.tail = list.head; } else { list.tail->next = newNode; list.tail = newNode; } }
2. 修改findByInvoiceId方法
调用调整后的add函数,传入原节点的数据副本而非原节点指针:
List<InvoiceDetails> findByInvoiceId(const List<InvoiceDetails> &list, int invoiceId) { List<InvoiceDetails> result; Node<InvoiceDetails> *current = list.head; while (current != NULL) { if (current->data.invoiceId == invoiceId) { // 添加数据副本,创建独立的新节点 add(result, current->data); } current = current->next; } return result; }
额外注意事项
- 后续需要实现链表的内存释放逻辑,避免内存泄漏。
- 如果必须复用原节点,可采用“视图链表”模式(仅保存节点指针但不修改原节点的
next),但这种方式容易引发野指针问题,推荐优先使用创建数据副本的方案。
内容的提问来源于stack exchange,提问作者chinhpc
相关产品推荐
相关产品推荐

