Iteratoren nach list::merge ungültig



  • Hallo,

    ich brauche eine kleine Hilfe und zwar habe ich zwei Listen die Objekte enthalten. Die Objekte enthalten zwei Iteratoren und verschiedene int-Werte. Verschmelze ich nun zwei Listen, wobei ich eine eigene compare-Methode erstellt habe, so werden einige Iteratoren ungültig.
    Weiß jemand woran es liegen könnte? Eigentlich habe ich gelesen, dass Iteratoren, die auf Objekte in egal welcher der beiden Mengen zeigen, weiterhin ihre Gültigkeit behalten. Liegt es vllt daran, dass ich meine eigene compare-Methode geschrieben habe? Und wenn ja, hat jemand eine Idee, wie man den Fehler beheben kann? Die Iteratoren berühre ich beim Vergleich gar nicht, deshalb weiß ich nicht warum sie auf einmal ungültig sind.

    Vielen Dank für jegliche Hilfe!



  • Iteratoren werden nicht ungültig, da keine Speicherblöcke bewegt werden.
    Sie werden vermutlich durch irgendeinen anderen Teil des Codes ungültig, den du uns nicht zeigst -> zeig ihn uns.



  • Also da ich die Referenzen vor dem mergen nochmal ausgegeben hab, weiß ich, dass sie da noch gültig waren. Hier ist meine Compare-Methode

    bool compare(int k, int j){
    	int i;
    	if(E[j].get_v()==E[k].get_v() || E[j].get_v()==E[k].get_w()){
    		i=E[j].get_v();
    	}
    	if(E[j].get_w()==E[k].get_v() || E[j].get_w()==E[k].get_w()){
    		i=E[j].get_w();
    	}
    	return E[j].get_opposite(i)<E[k].get_opposite(i);
    }
    

    und meine Klasse edge

    class edge{
    	int index;
    	int v;
    	int w;
    	list<int>::iterator Iv_pos;
    	list<int>::iterator Iw_pos;
    public:
            int get_v(){return v};
    	int get_w(){return w};
    	int get_opposite(int i){
            if(i==v){return w;}
    	else {return v}};
    

    Die Listen die ich verschmelzen will sind Inzidenzlisten. Ich möchte die Inzidenzlisten nach der Nummerierung der benachbarten Knoten sortieren, deshalb frage ich bei der compare-Methode erstmal ab in welcher Inzidenzliste ich mich befinde.



  • Womba schrieb:

    Also da ich die Referenzen vor dem mergen nochmal ausgegeben hab, weiß ich, dass sie da noch gültig waren.

    Das heißt nichts. Es könnten einfach nur noch zufällig die alten Daten in der selben Speicherposition liegen. Die Iteratoren werden nicht durch das merge ungültig!
    Aktivere mal den Debugmodus deiner Library (unter GCC mit -D_GLIBCXX_DEBUG) und/oder poste mehr Code.



  • bool ci_ende=false;
    bool cj_ende=false;
    I[cj].sort(compare);
    I[ci].sort(compare);
    itListj=I[cj].begin();
    itList=I[ci].begin();
    if(itListj==I[cj].end()){
    	cj_ende=true;
    }
    if(itList==I[ci].end()){
    	ci_ende=true;
    }
    double hilf;
    list<int> dummy;
    /*Die Inzidenzlisten der beiden Knoten ci und cj werden durchgegangen*/
    while(ci_ende==false && cj_ende==false){
    	if(E[*itList].get_opposite(ci)==E[*itListj].get_opposite(cj)){
    		hilf=E[*itList].get_delta()+E[*itListj].get_delta();
    		E[*itListj].set_delta(hilf);
    		I[E[*itList].get_opposite(ci)].erase(E[*itList].get_pos(ci));
    		++itListj;
    		++itList;
    		if(itListj==I[cj].end()){
    			cj_ende=true;
    		}
    		if(itList==I[ci].end()){
    			ci_ende=true;
    		}
    	}
    	else if(E[*itListj].get_opposite(cj)>E[*itList].get_opposite(ci)){
    	        //nur ci ist Nachbar
    		hilf=E[*itList].get_delta()-20;
    		E[*itList].set_delta(hilf);
    		dummy.push_back(*itList);
                    //da Knoten ci gelöscht wird, wird der Endknoten von ci in cj 
                    //umbenannt und der zugehörige Iterator auf den letzten Eintrag
                    //in dummy gesetzt
    		if(E[*itList].get_w()==ci){			     
                            E[*itList].set_w(cj);
     			E[*itList].set_w_pos(--dummy.end());
    		}
    		else if(E[*itList].get_v()==ci){
    			E[*itList].set_v(cj);
    			E[*itList].set_w_pos(--dummy.end());
    		}
    		++itList;
    		if(itList==I[ci].end()){
    			ci_ende=true;
    		}
    	}
    	else{
    		//nur cj ist Nachbarn
    		hilf=E[*itListj].get_delta()-20;
    		E[*itListj].set_delta(hilf);
    		++itListj;
    		if(itListj==I[cj].end()){
    			cj_ende=true;
    		}
    	}
    }
    //I[cj] wird mit Liste dummy verschmolzen	
    I[cj].merge(dummy,compare);
    

    sorry für das ungenaue Einrückungen aber irgendwie krieg ich das grad nicht hin.
    Ich gehe beide Inzidenzlisten durch und gucke, ob beide Knoten oder nur einer (und dann welcher) mit den Nachbarknoten verbunden ist. Je nachdem welcher gibts ne andere Regel um delta zu updaten und ci muss überall in cj umgeändert werden, weil ci nachher gelöscht wird.



  • darf man vllt Objekte nicht verändern, wenn ein Iterator auf sie zeigt?


  • Mod

    Womba schrieb:

    darf man vllt Objekte nicht verändern, wenn ein Iterator auf sie zeigt?

    Nein, das ist nicht der Fall.

    Ansonsten:
    -Compilierbares Minimalbeispiel erstellen! (Und im Idealfall dabei den Fehler selber finden)
    -Lesbar einruecken! Gib dir ein bisschen Muehe, schliesslich willst du Hilfe. Wenn du nicht einmal vernuenftig einrueckst, was ist dann von deiner Programmlogik zu erwarten?
    -Korrekte Codetags benutzen. Entweder den richtigen Button nutzen ("C++", unter dem 😞 -Smiley) oder von Hand mittels [code="cpp"].

    Je lesbarer ein Beitrag ist und je weniger Muehe sich jemand geben muss, um dein Problem nachzuvollziehen, desto mehr, bessere und schnellere Antworten wirst du erhalten. Du wirst ueberrascht sein, ueber den Unterschied. Derzeit ist dein Code schwer zu lesen und der Leser muss zudem viel muehselig raten, was wohl was ist. Wenn da hingegen Code steht, den man einfach direkt kopieren und ausfuehren kann, am besten mit genauer Beschreibung, was du erwartest und was stattdessen passiert, dann ist das fast ueberhaupt keine Muehe. Und wenn es zudem noch lesbar formatiert ist, dann findet ein erfahrener Programmierer viele Fehler sogar direkt beim ersten Durchlesen.



  • In meinem Programm ist der Code perfekt eingerückt aber bei der Übertragung hab ich das nicht hinbekommen. Ich bin neu hier, aber hab mir schon mühe gegeben und bin auch wirklich dankbar über jede hilfe. Ich scheitere nur grad dadran meinen Code auf 60 Zeilen zu minimieren. Ich versuchs mal weiter...


  • Mod

    Womba schrieb:

    In meinem Programm ist der Code perfekt eingerückt aber bei der Übertragung hab ich das nicht hinbekommen.

    Eventuell benutzt dein Editor Tabs zum Einruecken oder - noch schlimmer - Tabs und Leerzeichen gemischt. Versuch mal, nur Leerzeichen zu nutzen. Wenn du nicht weisst, wie du deinem Editor/IDE das beibringst (und bei Google nicht fuendig wurdest), dann frag hier unter Angabe deines Editors nach.



  • Ok ich konnte mein Problem umgehen. Danke für eure Hilfe!



  • Umgehen hört sich fies an.

    Aber wäre eigentlich ganz nett, grob zu sagen, was du falsch hattest oder jetzt machst.



  • Lasst doch mal die Unterstiche bei den Methoden- und Variabelnamen weg, die sehen aus wie Leerzeichen beim Drüberlesen und zerschießen jeden optischen Zusammenhang.



  • Ich bin nach dem mergen nochmal die Liste durchgegangen und hab die Iteratoren neu gesetzt. Was ich falsch hatte, weiß ich leider nicht.


Anmelden zum Antworten