C++链表按位置删节点的输入越界验证异常及代码优化
链表位置删除函数的问题修复与优化方案
问题背景
你需要实现一个基于位置删除链表节点的函数,核心需求包括:
- 维护
size变量(新增节点自增,删除节点自减) - 输入位置越界时(大于链表长度),重复获取用户输入
- 修复原函数的内存泄漏问题,解决越界输入时程序异常结束的bug
原代码的问题分析
先看你的原删除函数代码:
void delete_position(int pos) //delete node with given position { node *current=new node; node *previous=new node; current=head; if(head==NULL) { cout<<"You haven't ordered any cake(s)"<<endl; } for(int i=1;i<pos;i++) { previous=current; current=current->next; } previous->next=current->next; if(pos == 1){ node *temp=new node; temp=head; head=head->next; delete temp; } size--; }
这里存在几个关键问题:
- 严重内存泄漏:
current、previous、temp都被不必要地用new node分配了内存,但随后直接被指向链表的现有节点,导致新分配的内存永远无法释放,造成内存泄漏。 - 野指针与逻辑冲突:当
pos==1时,for循环不会执行,previous是未初始化的野指针,执行previous->next=current->next会直接引发程序崩溃;同时pos==1的分支逻辑和前面的通用删除逻辑重复,导致逻辑混乱。 - 越界处理缺失:没有对
pos的有效性做检查,当pos大于链表长度时,current会被遍历到NULL,后续访问current->next会触发未定义行为,这也是你遇到“输入4但链表只有2个节点时程序直接结束”的原因。
优化后的解决方案
优化后的代码修复了上述所有问题,并且逻辑更清晰:
void delete_position(int pos) //delete node with given position { node *current = head; if(size == 1){ head=NULL; tail=NULL; } else{ if(pos == 1){ head = head->next; }else{ node *previous = NULL; for(int i=1; i<pos; i++){ previous = current; current = current->next; } if(current == tail){ previous->next =NULL; tail = previous; }else{ previous->next = current->next; } } delete current; size--; }
优化点说明:
- 彻底修复内存泄漏:不再随意分配不必要的节点,只操作链表中已存在的节点,最后通过
delete current正确释放被删除节点的内存。 - 完善边界场景处理:
- 当链表只有1个节点时,直接清空
head和tail,避免后续指针错误 - 删除头节点时直接更新
head指针 - 删除尾节点时同步更新
tail指针,保证链表结构的完整性
- 当链表只有1个节点时,直接清空
- 为输入验证铺路:现在函数本身的逻辑已经稳定,你只需要在获取用户输入的地方添加
do-while循环做越界验证即可,示例代码如下:
// 获取用户输入并做越界验证 int pos; do { cout << "请输入要删除的位置(1~" << size << "):"; cin >> pos; if (pos < 1 || pos > size) { cout << "位置无效!请输入1到" << size << "之间的数字。" << endl; } } while (pos < 1 || pos > size); // 调用优化后的删除函数 delete_position(pos);
这段验证逻辑会在用户输入越界时重复提示,直到输入有效的位置为止。
内容的提问来源于stack exchange,提问作者mrtammy
相关产品推荐
相关产品推荐

