这与具有类似名称的问题不重复,这涉及OOP以及新呼叫和删除呼叫。
我正在尝试编写一个函数,它将迭代到我的链表的后面,然后删除最后一个节点的堆中分配的内存。
这是我的代码:
void LinkedList::delete_back(){
if(head != NULL){
ListNode *end = head;
while(end->next != NULL)
end = end->next;
delete end;
}
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的错误消息垃圾邮件,一些说明无效读取大小4,其他说明无效读取大小8:
==4385== Invalid read of size 4
==4385== at 0x400CAA: LinkedList::print() (in /home/jon/jball2_lab06/linkedlist)
==4385== by 0x400EDD: main (in /home/jon/jball2_lab06/linkedlist)
==4385== Address 0x5a04f30 is 0 bytes inside a block of size 16 free'd
==4385== at 0x4C2A4BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4385== by 0x400C5E: LinkedList::delete_back() (in /home/jon/jball2_lab06/linkedlist)
==4385== by 0x400E99: main (in /home/jon/jball2_lab06/linkedlist)
如果有帮助我会发布其余的错误,但除非我需要,否则我不想在50行上打4次。有谁知道这可能是什么?我做错了什么?
UPDATE ----------------------- 我已将代码编辑为:
void LinkedList::delete_back(){
if(head != NULL){
ListNode *end = head;
ListNode *prev_end;
while(end->next != NULL){
prev_end = end;
end = end->next;
}
prev_end->next = NULL;
if(end != NULL) delete end;
size--;
}
}
我现在收到更多关于8/4大小错误和无效/删除错误的无效读取
==5294== Invalid free() / delete / delete[] / realloc()
==5294== at 0x4C2A4BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
和此:
==5294== Use of uninitialised value of size 8
==5294== at 0x400C3D: LinkedList::delete_back() (in /home/jon/jball2_lab06/linkedlist)
==5294== by 0x400EEC: main (in /home/jon/jball2_lab06/linkedlist)
以下是使用的测试代码:
for(Item i = 50; i < 100; i++){
ll.insert_back(i);
cout << "Inserted [" << i << "] in back.\n";
}
ll.print();
for(int i = 0; i < 50; i++)
ll.delete_back();
cout << "Removed 50 elements from the back.\n";
ll.print();
使用delete_back()
从列表中删除最后一个元素时会发生这种情况UPDATE -------------------------
问题在于,如果end-&gt; next为null,而while循环将永远不会执行,则prev_end将永远不会被初始化。发布了已实施修复的答案。
答案 0 :(得分:4)
如果列表中包含至少2个节点,则delete
表示最后一个节点。前一个仍然引用了最后一个(不再存在),在print
尝试取消引用无效(悬空)指针时导致未定义行为。而不是:
ListNode *end = head;
while(end->next != NULL)
end = end->next;
delete end;
你应该这样做:
if (head->next == NULL) {
delete head;
head = NULL;
}
else {
ListNode *nextToEnd = head;
ListNode *end = head->next;
while (end->next != NULL) {
nextToEnd = end;
end = end->next;
}
delete end;
nextToEnd->next = NULL;
}
答案 1 :(得分:1)
不要忘记更新新的最后一个元素的next
。
void LinkedList::delete_back(){
if(head != NULL){
ListNode *end = head;
ListNode *prev_end;
while(end->next != NULL)
{
prev_end = end;
end = end->next;
}
prev_end->next = 0;
delete end;
}
此外,如果清空列表,请将head设置为NULL。
答案 2 :(得分:1)
您没有将新的结束节点设置为null。
例如:
A-&GT; B-&GT; C-&GT; NULL
删除C时,B的下一个是悬空指针
因此,在delete函数中,您需要转到倒数第二个节点,并将其下一个节点设置为NULL。
在删除C后的上述示例中,列表应如下所示
A-> B-> NULL而不是A-> B->(悬空)
所以你可以在下一个delete_back操作中删除B.
您可以执行以下操作
void LinkedList::delete_back(){
if(head != NULL){
ListNode *end = head;
//This if block is for when only one element is left
if(end->next == NULL)
{ delete end;
end = NULL;
}
else
while(end!= NULL)
{
if(end->next) /// reach the second last element
if(end->next->next==NULL)
{
delete end->next; //delete the last element
end->next=NULL; // set the next of second last element to NULL
}
end=end->next;
}
size--;
}
}
答案 3 :(得分:0)
修正了所有问题。
代码:
void LinkedList::delete_back(){
if(head != NULL){
ListNode *end = head;
if(end->next != NULL){
ListNode *prev_end;
while(end->next != NULL){
prev_end = end;
end = end->next;
}
prev_end->next = NULL;
delete end;
}
else {
delete head;
head = NULL;
}
size--;
}
}
答案 4 :(得分:0)
像这样应该工作
void del_rear()
{
struct node *end, *last
if (head->next != NULL) {
*end=head;
while(end->next!=null){
*last=end;
end=end->next;
}
free(end);
last->next=null;
}
else
{
pf("list is empty\n");
}
}
答案 5 :(得分:0)
最简单的删除代码是:
void DeleteAtLast(){
node *temp=head;
while(temp->next->next!=NULL){
temp=temp->next;
}
temp-next=NULL;
}