为什么这个程序会用delete命令中断



我想从链表中删除某个元素(它是一个数字列表)。当我找到正确的数字时,我会检查前一个元素是否为NULL。如果是,它就是列表的头,我只需要移动指针,如果不是,我会重新链接元素,这样上一个元素就会指向要删除的元素的下一个元素。

现在,这很好用,除非我取消注释以下命令:

delete old;

现在,old是一个指针,指向需要删除的元素。我想删除元素,而不仅仅是重新链接列表。

// zag.h - header file
#ifndef _zag_h_
#define _zag_h_
#include <iostream>
using namespace std;
struct Elem {
int n;
Elem* next;
Elem(int bbr,Elem* nex = NULL){n = bbr; next = nex;}
~Elem(){delete next;}
};
class Lista {
Elem* head;
public:
Lista(){
    head=NULL;
}
~Lista(){
}
void put(int broj){
    Elem* temp = new Elem(broj);
    Elem* n0 = NULL;
    Elem* n1 = head;
    while(n1!=NULL && temp->n >= n1->n){
        n0 = n1;
        n1 = n1->next;
    }
    if(n0 == NULL){
        temp->next=head;
        head = temp;
    }
    else {
        n0->next = temp;
        temp->next = n1;
        //if(n1==NULL)tail=temp;
    }
    //cout << head->n << endl;
}
void remove(int num){
    Elem* n1 = head;
    Elem* n0 = NULL;
    while(n1!=NULL && n1->n!= num){
        n0 = n1;
        n1 = n1->next;
    }

    if(n0 == NULL){
        Elem* old = n1;
        head = head->next;
        n1 = n1->next;
        delete old;
    }
    else {
        Elem* old = n1;
        n1 = n1->next;
        n0->next = n1;
        cout << old->n;
        delete(old);
    }

}//remove
void write(){
    Elem* temp = head;
    while(temp){
        cout << temp->n << " ";
        temp = temp->next;
    }
    cout<<endl;
} //ispisi
};
#endif

// main.cpp file
#include "zaglavlje.h"
#include <iostream>
using namespace std;
void main(){
cout << "Welcome " << endl;
Lista* l = new Lista();
l->put(4);
l->put(2);
l->put(8);
l->put(7);
l->put(6);
l->put(9);
l->put(11);
l->put(15);
l->put(17);
l->put(2);
l->put(1);
l->write();
l->remove(11);
//l->remove(2);
//l->remove(2);
//l->remove(11);
//l->remove(15);

cout << "ispisujemo elemente liste nakon brisanja" << endl;
l->ispisi();
}

因此,我在列表中插入一些元素,编写列表元素(看起来都很好),然后调用一个函数来删除一个元素。之后,当我尝试写列表(检查元素是否真的被删除)时,我得到了以下错误:

An unhandled win32 exception occurred in test.exe

调试器指向线

cout << temp->n << " ";

在写入功能中。

如果不调用delete old命令,一切都可以正常工作。

当您的列表为空时,您无论如何都在尝试访问"第一个"元素:

if (n0 == NULL && n1 == NULL)
{
    // empty list, do nothing
}
else if (n0 == NULL && n1 != NULL)
{
    Elem* old = n1;
    head = head->next;
    n1 = n1->next;
    delete old;
}
else 
{
    Elem* old = n1;
    n1 = n1->next;
    n0->next = n1;
    delete old;
}

当您删除当前代码中的delete时,您会保留已分配的内存,这样当您访问错误时就不会出现访问冲突。当您将它们添加回时,您正在访问的内存在列表为空时不再分配。

当您第一次运行程序时,如果head未初始化,这也将是一个问题。

最新更新