Problem mit vielen Referenzen



  • Hallo!

    Ich habe hier Code bekommen. Da wird eine LinkedList (manuell) gebaut, die Zeiger auf etwas enthält. Jetzt würde ich gerne auf einen dieser Zeiger, die in dem Element der LinkedList enthalten sind zugreifen und die dort referenzierten Daten dauerhaft verändern.
    Das geht nicht:

    // gibt einen Zeiger auf das modifizierte Listen-Element zurück
    	ListNode* getAndDelMinimum() {
    		// suche ein Element heraus
    		ListNode* min_freq_elem = this->findMinimum();
    		// ändere was an dem Referenzierten Element
    		this->deleteListNode(min_freq_elem);
    
    		return min_freq_elem;
    	}
    
    	void deleteListNode( ListNode* node ) {
    		// an einen Zeiger auf das Element kommen wir mit getTree()
    		// setUsed(bool) modifiziert etwas
    		node->getTree()->setUsed(true);
    	}
    

    Bitte um eure Hilfe, ich bin in Sachen Zeigern leider immer noch nicht so firm.

    Grüße, pktm



  • Fehlermeldung? Beim Kompilieren, oder vielleicht zur Laufzeit? Oder fehlt einfach der gewünschte Effekt? Was geht nicht und wie geht es nicht?



  • _matze schrieb:

    Fehlermeldung? Beim Kompilieren, oder vielleicht zur Laufzeit? Oder fehlt einfach der gewünschte Effekt? Was geht nicht und wie geht es nicht?

    Ahja, die Info fehlt ja noch 🙂
    Also, es kommt keine Fehlermeldung, aber es passiert nichts. Ich rufe die Funktion getAndDelMinimum() für eine Instanz der LinkedList auf, aber der Wert des Elements, welches eigentlich in deleteListNode() erändert werden sollte ändert sich nicht.
    Ich habe mir das ausgeben lassen, vor und nach dem Aufruf der Methode, und der Wert, der da verändert wird bleibt gleich (er bleibt auf false, so wie er initialisiert wird).

    Daher dachte ich, ich rufe die Sache vllt. irgendwie falsch auf.



  • Hmm, kein Compiler-Fehler, syntaktisch ist also alles richtig und die Dereferenzierungen stimmen. Da hilft nur schrittweise mit dem Debugger durchlaufen. Hast du mal geguckt, ob findMinimum() auch das richtige Element findet? An einen NULL-Zeiger glaube ich nicht, da müsste es ja wahrscheinlich beim setUsed()-Aufruf krachen.



  • _matze schrieb:

    Hmm, kein Compiler-Fehler, syntaktisch ist also alles richtig und die Dereferenzierungen stimmen. Da hilft nur schrittweise mit dem Debugger durchlaufen. Hast du mal geguckt, ob findMinimum() auch das richtige Element findet? An einen NULL-Zeiger glaube ich nicht, da müsste es ja wahrscheinlich beim setUsed()-Aufruf krachen.

    Also, findminimum findet das richtige Element. Das Attribut des Elements wird auch verändert. Aber: das ganz ist innerhalb einer Schleife. Und wenn ich innerhalb des Codeblocks der Schleife Änderungen an der Liste durchführe sind die irgendwie hinterher beim nächsten Durchlauf nicht mehr da!?

    Voll komisch :-s

    Hier die Schleife (dieser dbg_cnt ist da, weil auf Grund des sich nicht ändernden Attributs die Methode isOnlyOneElementLeft() nicht mehr funktioniert):

    void Compress::createTree() {
    	if(DEBUG) { cout << "Compress.createTree()\n"; }
    
    	HuffmanTreeNode *tnode1;
    	HuffmanTreeNode *tnode2;
    
    	int dbg_cnt = 0;
    	while( dbg_cnt < 5 && !this->_list->isOnlyOneElementLeft() ) {
    
    		tnode1 = this->_list->getAndDelMinimum()->getTree();
    		tnode2 = this->_list->getAndDelMinimum()->getTree();
    
    		// mach was mit den Dingern...
    
    		// DEBUG-CNT
    		dbg_cnt++;
    		if( dbg_cnt >= 10 ) {
    			cout << "DEBUG: Abbruch durch Debug-Begrenzung!";
    		}
    
    	}
    
    	// last element is final tree
    	_tree = _list->getHead()->getTree();
    	cout << "\nCpmress.Treefreq:" << _tree->getFreq();
    
    }
    


  • Ich verstehe nicht ganz, was diese Funktion machen soll:

    ListNode* getAndDelMinimum() { 
            // suche ein Element heraus 
            ListNode* min_freq_elem = this->findMinimum(); 
            // ändere was an dem Referenzierten Element 
            this->deleteListNode(min_freq_elem); 
    
            return min_freq_elem; 
        }
    

    Sie löscht ein Element und gibt dann einen Zeiger auf das gelöschte Element zurück??



  • _matze schrieb:

    Ich verstehe nicht ganz, was diese Funktion machen soll:

    ListNode* getAndDelMinimum() { 
            // suche ein Element heraus 
            ListNode* min_freq_elem = this->findMinimum(); 
            // ändere was an dem Referenzierten Element 
            this->deleteListNode(min_freq_elem); 
            
            return min_freq_elem; 
        }
    

    Sie löscht ein Element und gibt dann einen Zeiger auf das gelöschte Element zurück??

    Ja, so die ursprüngliche Idee der Originalautorin. Wir haben die Methode so verändert, dass keine Elemente mehr aus der Liste gelöscht werden, sondern nur noch als benutzt markiert werden:

    /**
     * entferne "element" aus der LinkedList (= setze Attribut used auf true)
     * alt. Kommentar: Vermerke, dass das Element benutzt wurde (richtig gelöscht wird es nicht mehr).
     * TODO: Methode umbenennen, z.B. in remember_being_used().
     * TODO: Da diese Änderung die Liste ansich nicht betrifft, könnte der im Listenelement
     * eingebettete HuffmanTreeNode auch direkt manipuliert werden. Fragt sich nur, wie
     * sauber das dann noch ist => Mergen von HuffmanTreeNode & LinkedList.
     */
    void LinkedList::deleteListNode( ListNode* node ) {
    	node->getTree()->setUsed(true);
    }
    

    Grüße, pktm


Anmelden zum Antworten