在链表中没有添加虚拟头结点的情况下,删除链表第一个节点程序报错。
来源:5-3 设立链表的虚拟头结点 Remove Linked List Elements
沙皮狗yy
2017-07-22
#include <iostream>
using namespace std;
///Definition for singly-linked list.
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
/// LinkedList Test Helper Functions
ListNode* createLinkedList(int arr[], int n){
if( n == 0 )
return NULL;
ListNode* head = new ListNode(arr[0]);
ListNode* curNode = head;
for( int i = 1 ; i < n ; i ++ ){
curNode->next = new ListNode(arr[i]);
curNode = curNode->next;
}
return head;
}
void printLinkedList(ListNode* head){
if( head == NULL ){
cout<<"NULL"<<endl;
return;
}
ListNode* curNode = head;
while( curNode != NULL ){
cout<<curNode->val;
if( curNode->next != NULL )
cout<<" -> ";
curNode = curNode->next;
}
cout<<endl;
return;
}
void deleteLinkedList(ListNode* head){
ListNode* curNode = head;
while( curNode != NULL ){
ListNode* delNode = curNode;
curNode = curNode->next;
delete delNode;
}
return;
}
// 不使用虚拟头结点
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//在循环过程中不断的访问head—>val,
//要保证每次进入循环时head都不为空!
while( head != NULL && head->val == val ){
ListNode* node = head;
head = head->next;
delete node;
}
//执行完上面的操作之后,就会由一个新的head
//此时也要保证head不为NULL
if( head == NULL )
return head;
ListNode* cur = head;
while( cur->next != NULL ){
if( cur->next->val == val ){
ListNode* delNode = cur->next;
cur->next = delNode->next;
delete delNode;
}
else
cur = cur->next;
}
return head;
}
};
int main() {
int arr[] = {1, 2, 6, 3, 4, 5, 6};
int n = sizeof(arr)/sizeof(int);
ListNode* head = createLinkedList(arr, n);
printLinkedList(head);
Solution().removeElements( head, 1);
printLinkedList(head);
deleteLinkedList( head );
return 0;
}老师您好,上面是完整的代码,我删除第一个节点时,按照您的代码,程序会报错。
下面是我用gdb调试的结果,看调试的结果是 在deleteLinkedList()这个函数中调用delete delNode;这个语句时报错!
而且删除了头结点之后打印的结果是0 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6,从调试结果看只是把头结点的val给置0了,并没有真正delete掉这个节点。
Breakpoint 1, main () at main.cpp:93
93 int arr[] = {1, 2, 6, 3, 4, 5, 6};
(gdb) n
94 int n = sizeof(arr)/sizeof(int);
(gdb) n
96 ListNode* head = createLinkedList(arr, n);
(gdb) n
97 printLinkedList(head);
(gdb) n
1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
99 Solution().removeElements( head, 1);
(gdb) n
100 printLinkedList(head);
(gdb) n
0 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
102 deleteLinkedList( head );
(gdb) s
deleteLinkedList (head=0x603010) at main.cpp:50
50 ListNode* curNode = head;
(gdb) n
51 while( curNode != NULL ){
(gdb) n
52 ListNode* delNode = curNode;
(gdb) n
53 curNode = curNode->next;
(gdb) n
54 delete delNode;
(gdb) n
*** Error in `/root/yuyang/program/liuyubo2/05-About-Linked-List/Course Code (C++)/03-Remove-Linked-List-Elements/a.out': double free or corruption (fasttop): 0x0000000000603010 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7c503)[0x7ffff7277503]
/root/yuyang/program/liuyubo2/05-About-Linked-List/Course Code (C++)/03-Remove-Linked-List-Elements/a.out[0x400abe]
/root/yuyang/program/liuyubo2/05-About-Linked-List/Course Code (C++)/03-Remove-Linked-List-Elements/a.out[0x400b5a]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7ffff721cb35]
/root/yuyang/program/liuyubo2/05-About-Linked-List/Course Code (C++)/03-Remove-Linked-List-Elements/a.out[0x400889]
======= Memory map: ========
00400000-00401000 r-xp 00000000 ca:01 1983859 /root/yuyang/program/liuyubo2/05-About-Linked-List/Course Code (C++)/03-Remove-Linked-List-Elements/a.out
00601000-00602000 r--p 00001000 ca:01 1983859 /root/yuyang/program/liuyubo2/05-About-Linked-List/Course Code (C++)/03-Remove-Linked-List-Elements/a.out
00602000-00603000 rw-p 00002000 ca:01 1983859 /root/yuyang/program/liuyubo2/05-About-Linked-List/Course Code (C++)/03-Remove-Linked-List-Elements/a.out
00603000-00624000 rw-p 00000000 00:00 0 [heap]
7ffff0000000-7ffff0021000 rw-p 00000000 00:00 0
7ffff0021000-7ffff4000000 ---p 00000000 00:00 0
7ffff71fb000-7ffff73b2000 r-xp 00000000 ca:01 1507907 /usr/lib64/libc-2.17.so
7ffff73b2000-7ffff75b1000 ---p 001b7000 ca:01 1507907 /usr/lib64/libc-2.17.so
7ffff75b1000-7ffff75b5000 r--p 001b6000 ca:01 1507907 /usr/lib64/libc-2.17.so
7ffff75b5000-7ffff75b7000 rw-p 001ba000 ca:01 1507907 /usr/lib64/libc-2.17.so
7ffff75b7000-7ffff75bc000 rw-p 00000000 00:00 0
7ffff75bc000-7ffff75d1000 r-xp 00000000 ca:01 1510624 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7ffff75d1000-7ffff77d0000 ---p 00015000 ca:01 1510624 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7ffff77d0000-7ffff77d1000 r--p 00014000 ca:01 1510624 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7ffff77d1000-7ffff77d2000 rw-p 00015000 ca:01 1510624 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7ffff77d2000-7ffff78d2000 r-xp 00000000 ca:01 1510688 /usr/lib64/libm-2.17.so
7ffff78d2000-7ffff7ad2000 ---p 00100000 ca:01 1510688 /usr/lib64/libm-2.17.so
7ffff7ad2000-7ffff7ad3000 r--p 00100000 ca:01 1510688 /usr/lib64/libm-2.17.so
7ffff7ad3000-7ffff7ad4000 rw-p 00101000 ca:01 1510688 /usr/lib64/libm-2.17.so
7ffff7ad4000-7ffff7bbd000 r-xp 00000000 ca:01 1507953 /usr/lib64/libstdc++.so.6.0.19
7ffff7bbd000-7ffff7dbd000 ---p 000e9000 ca:01 1507953 /usr/lib64/libstdc++.so.6.0.19
7ffff7dbd000-7ffff7dc6000 r--p 000e9000 ca:01 1507953 /usr/lib64/libstdc++.so.6.0.19
7ffff7dc6000-7ffff7dc8000 rw-p 000f2000 ca:01 1507953 /usr/lib64/libstdc++.so.6.0.19
7ffff7dc8000-7ffff7ddd000 rw-p 00000000 00:00 0
7ffff7ddd000-7ffff7dfd000 r-xp 00000000 ca:01 1507900 /usr/lib64/ld-2.17.so
7ffff7fed000-7ffff7ff2000 rw-p 00000000 00:00 0
7ffff7ff7000-7ffff7ffa000 rw-p 00000000 00:00 0
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 0001f000 ca:01 1507900 /usr/lib64/ld-2.17.so
7ffff7ffd000-7ffff7ffe000 rw-p 00020000 ca:01 1507900 /usr/lib64/ld-2.17.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Program received signal SIGABRT, Aborted.
0x00007ffff72301d7 in raise () from /lib64/libc.so.6看了很久的代码,不知道问题出在哪里,麻烦老师能解答一下
写回答
1回答
-
我没有运行你的代码,但是直观看下来有一个问题。当你在main函数运行这句话以后:
Solution().removeElements( head, 1);
你的main函数中的head指针已经被delete掉了,此时你后续的这些代码:
printLinkedList(head); deleteLinkedList( head );
访问这个head是危险的。当删除的是链表的头结点的时候,要把新的头结点返回赋值回来。改成这样:
head = Solution().removeElements( head, 1);
再试试看?加油!
122021-11-01
相似问题