0

リンクされたリスト(数字のリスト)から特定の要素を削除したい。正しい番号が見つかったら、前の要素が 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();
}

そのため、リストにいくつかの要素を挿入し、リスト要素を書き込み (すべて正常に動作しているようです)、関数を呼び出して 1 つの要素を削除します。その後、リストを書き込もうとすると(要素が本当に削除されているかどうかを確認するために)、次のエラーが発生します。

An unhandled win32 exception occurred in test.exe

そしてデバッガーは行を指します

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

書き込み機能で。

delete old コマンドを呼び出さなくても、すべて正常に動作します。

4

1 に答える 1

0

リストが空の場合、とにかく「最初の」要素にアクセスしようとしています:

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;
}

現在のコードで削除を削除すると、メモリが割り当てられたままになるため、誤ってアクセスしてもアクセス違反は発生しません。それらを再度追加すると、リストが空のときに割り当てられなくなったメモリにアクセスしています。

これは、初期化されていないプログラムを最初に実行するときにも問題になりますhead

于 2013-08-16T19:36:37.597 に答える