我正在尝试编写一个删除链表前面元素的函数,并将头指针设置为删除后的下一个元素。
这是我的代码:
void LinkedList::delete_front(){
if(head != NULL){
if(head->next != NULL){
ListNode *tmp = head;
delete head;
head = tmp->next;
}
else {delete head; head = NULL;}
}
size--;
}
这是我的班级定义:
class ListNode{
public:
Item data;
ListNode *next;
};
class LinkedList{
private:
ListNode *head;
int size;
public:
LinkedList();
~LinkedList();
bool empty();
void insert_front(Item i);
void insert_back(Item i);
void delete_front();
void delete_back();
void print();
};
Annddddd .....这是问题,当在valgrind中运行时,在第一次delete_front()调用之前会弹出这个错误:
==4738== Invalid read of size 8
==4738== at 0x400B3C: LinkedList::delete_front() (in /home/jon/jball2_lab06/linkedlist)
==4738== by 0x400E59: main (in /home/jon/jball2_lab06/linkedlist)
==4738== Address 0x5a03f98 is 8 bytes inside a block of size 16 free'd
==4738== at 0x4C2A4BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4738== by 0x400B37: LinkedList::delete_front() (in /home/jon/jball2_lab06/linkedlist)
==4738== by 0x400E59: main (in /home/jon/jball2_lab06/linkedlist)
答案 0 :(得分:3)
您正在删除元素,之后,您尝试访问它。这些是:
ListNode *tmp = head;
delete head;
head = tmp->next; // tmp was initialized to head, but head was just deleted!
应该是:
ListNode *tmp = head->next;
delete head;
head = tmp;
更新:我刚刚意识到,通过上述方法,整个方法可以变得更加容易:
void LinkedList::delete_front()
{
if(head != NULL) {
ListNode *tmp = head->next;
delete head;
head = tmp;
--size;
}
}
适用于所有情况。您不必检查head->next == NULL
,因为上面也会处理它。它还修复了代码中的错误,即使列表为空,我在size
块内移动--size
,也会减少if(head != NULL)
。{/ p>
请注意,这会保留原始语义,即“如果列表为空,则不执行任何操作”。这通常不是你想要的,考虑抛出异常:
void LinkedList::delete_front()
{
if(head == NULL) {
throw std::runtime_exception( "LinkedList::delete_front() "
"called with empty list" );
}
ListNode *tmp = head->next;
delete head;
head = tmp;
--size;
}
答案 1 :(得分:3)
问题在这里:
if(head->next != NULL){
ListNode *tmp = head;
delete head;
head = tmp->next;
}
您将temp指定给head,然后删除head。然后尝试再次访问它。
答案 2 :(得分:1)
你的问题就在这里:
ListNode *tmp = head;
delete head;
head = tmp->next;
你将tmp设置为head,然后删除head,然后使用tmp。 tmp指向刚刚删除的内存。
相反,将tmp设置为head,将head设置为head-> next,然后删除tmp。
答案 3 :(得分:1)
如果您使用智能指针,它将缩减为:
void LinkedList::delete_front() {
if(head != NULL) {
head = head->next;
--size;
}
}
其中:
class ListNode{
public:
Item data;
unique_ptr<ListNode> next;
};
class LinkedList{
private:
unique_ptr<ListNode> head;
//.. etc
此外,即使head
为NULL
,我也已修复了尺寸减小的错误。