C++中单链表的new与delete运算符使用问题咨询
问题
用户提供的代码:
#include <iostream> #include <assert.h> using namespace std; struct node { int num; node *link; }; int main (void) { node *head, *tail; tail = new node; head = tail; int i = 1; while (i < 20) { tail -> num = i; tail -> link = new node; assert(tail->link != NULL); tail = tail->link; i++; } tail -> num = i; tail -> link = head; for (int x = 0;x<100;x++) { cout<<head->num<<" "; head = head->link; } delete head; return 0; }
这段代码可正常运行,但delete运算符的使用存在错误,位置不合适,不应仅释放head节点。希望释放所有通过new创建的节点,该如何操作?
解决方案
你的判断完全正确——这段代码只释放了单个节点,剩余19个节点会造成内存泄漏。循环链表的内存释放需要注意避免指针丢失和无限循环,以下是两种可靠的实现方式:
方法一:断开循环后遍历删除
先将循环链表转换为单链表,再按常规单链表的方式释放:
// 先定位到原始头节点(当前head已经被循环移动过,需要找回初始起点) node* originalHead = head; // 找到链表的尾节点(即原始头节点的前一个节点) node* temp = originalHead; while (temp->link != originalHead) { temp = temp->link; } // 断开循环,变成单链表 temp->link = nullptr; // 遍历释放所有节点 node* current = originalHead; while (current != nullptr) { node* nextNode = current->link; // 先保存下一个节点的指针 delete current; current = nextNode; }
方法二:按节点计数释放(已知节点总数)
由于你明确知道链表有20个节点,可以直接计数遍历释放:
node* current = head; for (int cnt = 0; cnt < 20; ++cnt) { node* nextNode = current->link; delete current; current = nextNode; }
关键注意点
- 必须先保存下一个节点的指针再删除当前节点,否则删除后无法访问后续节点。
- 若节点数量未知,优先使用方法一,避免因计数错误导致的内存泄漏或重复释放。
- 不要在无终止条件的循环中直接遍历删除循环链表,会陷入无限循环。
内容的提问来源于stack exchange,提问作者Zephyr Leone
相关产品推荐
相关产品推荐

