PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Verkettete Liste - Löschung von Gliedern



Odzilla
11-07-2005, 23:44
Hi,


ich habe eine verkettete Liste, die eine Datenklasse aufnimmt.
Die Glieder der Liste tragen zwei Zeiger: einen auf das vorherige und einen auf das nächste Glied.

cNode * myNext;
cNode * myLast;

Wenn ich jetzt ein Glied der Kette löschen will, setze ich zuerst die Zeiger, die auf dieses Glied zeigen (aus dem vorherigen und dem nächsten Glied) entsprechend.

myNext->myLast=myLast;
myLast->myNext=myNext;

Jetzt wäre das Glied aus der Kette gelöst und ich könnte es zerstören.

Das Problem ist nur, dass wann immer ich myNext oder myLast modifizieren will, ein Segmentation Fault ausgelöst wird. Selbst myNext=NULL; funktioniert nicht.

Das passiert aber nicht nur beim Modifizieren der beiden Zeiger, sondern auch beim Zugriff auf Memberfunktionen des nächsten/vorherigen Glieds. Hierbei funktionieren manche ... andere lösen ebenfalls einen Segmentation Fault aus.


Irgendwie kommt mir das ein wenig komisch vor ^^


Die BasisKlasse für die verkettete Liste:

class cNode
{
public:
cNode() {}
virtual ~cNode() {}
virtual cNode * Insert(cMyData * theData) = 0;
virtual void Show() = 0;
virtual cMyData * Search(cMyData * theData) = 0;
virtual void Run() {}
virtual void Run( cMyParse * test ) {}
virtual void Parse( cMyParse * test ) {}
virtual void Reset() {}
virtual void Del( cMyData * theData ) {}
void SetMyNext ( cNode * next ) {myNext = next;}
void SetMyLast ( cNode * last ) {myLast = last;}
cNode * GetMyNext () { return myNext; }
cNode * GetMyLast () { return myLast; }
cMyData * GetMyData () { return theData; }
void Destroy();

protected:
cNode * myNext;
cNode * myLast;
cMyData * theData;
};

Die Destroy() Funktion:

void cNode::Destroy()
{
myLast->SetMyNext(myNext);
myNext->SetMyLast(myLast);
}


Ich hoffe, das war in etwa verständlich :)
Wahrscheinlich hab ich eh nur wieder irgendwas dämliches vergessen, ärger mich aber schon den halben Tag damit rum ^^

anda_skoa
12-07-2005, 13:26
Vielleicht hast du beim Erzeugen der Nodes die Pointer nicht auf 0 initialisiert und wenn du später abfragst ob sie != 0 sind um festzustellen ob da ein Nachbarnode ist, greifst du in Wirklichkeit auf einen ungültigen Speicherbereich zu.

Ciao,
_

Odzilla
12-07-2005, 14:34
Hmm, beim erzeugen des Nodes werden immer schon beide Pointer auf die entprechenden Vorgänger und Nachfolger gesetzt.

Selbst beim ersten Glied dürfte das kein Problem sein, da am Anfang der Liste immer ein HeadNode steht und am Ende ein TailNode, somit müssen myLast und myNext immer gültig sein.
Bei dem ersten ist ausserdem myLast auf 0 gesetzt und beim letzten myNext, das sollte auch kein Problem darstellen.

Auch Sachen wie myLast->GetMyNext() oder ähnliches funktionieren.

Einizg Funktionen, die auf das Datensegment des nächsten oder vorherigen nodes zugreifen schienen nicht zu funktionieren.

EDIT:

An Vererbungen kanns nicht liegen, oder?
Hab ja eine grosse Datenklasse, die in verschiedenen Variationen abgeleitet wird.

void Destroy() { myNode->Destroy(); }
wird zum zerstören benutzt

Die Abgeleiteten Klassen müssen die Funktion doch ebenfalls so ausführen, one, dass es Probleme gibt, oder?

myNode wird bei jeder Tochterklasse neu definiert, die Destroy() Funktion jedoch nicht.
Das sollte doch in Ordnung gehen?

EDIT2:

Hab das Problem jetzt anscheinend gefunden. Aber ich hab keine Ahnung wies dazu kommen konnte.

Im Konstruktor von cInternalNode (einem Glied der Kette, das zwischen Anfang und Ende liegt) werden die ganzen Zeiger gesetzt.

cInternalNode::cInternalNode(cMyData * theData, cNode * next, cNode * last):
myData(theData),myNext(next),myLast(last)

Soweit, so gut.

Ich kann auch prima auf myData zugreifen.

Einzig die Funktion GetMyData(), die eigendlich in der Klasse cNode deklariert wird funktioniert, nicht so ganz.
Sie besteht nur aus "return myData", und obwohl ich direkt auf myData zugrifen kann, liefert GetMyData 0 zurück.

myData: 0x8054200
GetMyData(): 0

Ach ja: Oben hab ich ja cNode gepostet, da hat sich aber der Name der Datenvariable von theData auf myData geändert.

Hmm ob da noch wer durchblickt? *gg*

Odzilla
13-07-2005, 12:52
OK es geht jetzt.

Leider bin ich jetzt vollends verwirrt.
Irgendwas funktioniert bei der vererbung nicht. Ich hab jetzt allen Tochterklassen von cNode die wichtigen Funktionen nochmal deklariert ... aber das gibt doch keinen Sinn ... wofür ist Vererbung sonst da ^^

Naja hab ich wohl bei der Vererbung was falsch gemacht ... aber was?

Trotzdem thx an alle, die sich Gedanken gemacht haben :)

EDIT: Jetzt hab ichs mit der Vererbung auch geschafft :)