在链表中没有添加虚拟头结点的情况下,删除链表第一个节点程序报错。
来源: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
相似问题