Merkwürdiges Verhalten beim Durchlaufen einer List per Iterator



  • Hallo,
    danke für deine Antwort, aber "observers" habe ich nicht als Pointer deklariert. In der Liste selbst befinden sich Pointer auf andere Objekte.



  • Aus welchem Namespace kommt die Liste denn? Wo kommt der Namespace her? Hast Du std im Header in den globalen Namespace importiert? Nicht gut!



  • KasF schrieb:

    Firefighter schrieb:

    Falls ich falsch liege berichtig mich bitte.

    Das ist schon richtig so, schließlich ist observers selbst kein Zeiger, folgedessen nur ein observers.begin().

    Der Fehler muss woanders liegen, hier sind noch alles gut aus.

    Ahh stimmt...natürlich, da hatte ich nicht aufgepasst. Danke 🙂



  • Tachyon schrieb:

    Aus welchem Namespace kommt die Liste denn? Wo kommt der Namespace her? Hast Du std im Header in den globalen Namespace importiert? Nicht gut!

    Ach das habe ich vergessen, dazu zu schreiben:

    using namespace std;
    

    habe ich noch vor meiner Klasse stehen...

    Die Liste kommt aus std. Ist es gar nicht gut, im Header den Namespace zu importieren?

    Ich habe es nochmal probiert, ohne std zu importieren, aber daran liegt es leider auch nicht.



  • sunnyandy schrieb:

    Tachyon schrieb:

    Aus welchem Namespace kommt die Liste denn? Wo kommt der Namespace her? Hast Du std im Header in den globalen Namespace importiert? Nicht gut!

    Ach das habe ich vergessen, dazu zu schreiben:

    using namespace std;
    

    habe ich noch vor meiner Klasse stehen...

    Das ist schlecht. Man sollte niemals nicht in einem Header irgendwelche namespaces in den globalen Scope importieren.



  • Tachyon schrieb:

    sunnyandy schrieb:

    Tachyon schrieb:

    Aus welchem Namespace kommt die Liste denn? Wo kommt der Namespace her? Hast Du std im Header in den globalen Namespace importiert? Nicht gut!

    Ach das habe ich vergessen, dazu zu schreiben:

    using namespace std;
    

    habe ich noch vor meiner Klasse stehen...

    Das ist schlecht. Man sollte niemals nicht in einem Header irgendwelche namespaces in den globalen Scope importieren.

    OK danke für deinen Tipp, leider hat es auch nicht funktioniert.
    Ich habe die "observers" eben mal als Pointer deklariert und im Konstruktor ein Objekt erzeugt, nur leider hat das auch nichs gebracht.


  • Administrator

    Tachyon schrieb:

    Das ist schlecht. Man sollte niemals nicht in einem Header irgendwelche namespaces in den globalen Scope importieren.

    Korrekt und zwar weil:
    Du hebelst den Nutzen vom Namespace damit aus. Überall wo du den Header inkludierst, wird automatisch der entsprechende Namespace in den globalen Scope übertragen, was zu ungewollten Namenskonflikten führen kann, wovon der namespace ja eigentlich schützen sollte.

    Das kann auch sehr ärgerlich für Leute sein, welche deine Bibliotheken nutzen wollen.

    Man sollte sowieso so oft wie möglich auf using namespace verzichten. bei langen namespace Namen kann man auch sowas benutzen:

    namespace xml = dsi::bliblablub::nochwas::xml;
    

    so erreicht man das lange Ding direkt über den Namespace xml 😉

    Zu deinem Problem, zeig mal etwas mehr Code. So viel kann ja nicht passieren in der while-Schleife.

    Grüssli



  • Von dieser Klasse erbt übrigens eine Klasse, welche sich in einer SharedLibrary befindet. Kann das vielleicht mit irgendwelchen Speicherproblemen zusammenhängen?

    Die Liste muss doch initialisiert worden sein, oder? Ansonsten kann die Test-Ausgabe doch nicht tausendmal auf meinem Monitor ausgegeben werden, richtig?



  • Dravere schrieb:

    Zu deinem Problem, zeig mal etwas mehr Code. So viel kann ja nicht passieren in der while-Schleife.

    Grüssli

    Wenn die Liste leer ist, passiert gar nichts, weil er gar nicht in die Schleife rein gehen sollte.



  • [quote="Dravere"]

    Tachyon schrieb:

    Zu deinem Problem, zeig mal etwas mehr Code. So viel kann ja nicht passieren in der while-Schleife.
    Grüssli

    Aufgrund des Fehlers habe ich mittlerweile alles auskommentiert. In der while-Schleife passiert nicht mehr.
    Irgendwie scheint er die Liste nicht richtig zu erzeugen...



  • Was für einen Compiler benutzt Du denn?

    Schmeiss mal das #include "Observer.h" raus und ersetzte es durch struct Observer{}; .

    PS: Natürlich nur zum Testen. 😉


  • Administrator

    Tachyon schrieb:

    Wenn die Liste leer ist, passiert gar nichts, weil er gar nicht in die Schleife rein gehen sollte.

    a) Die Liste ist nicht leer. Sonst würde die Endlosschleife nicht starten!
    b) Eine Endlosschleife kann dann nur dadurch passieren, dass in der While-Schleife ein Problem ist.
    c) Dass die Liste Elemente aufweist, obwohl sie leer sein sollte, ist natürlich noch ein weiteres Problem, auf welches ich aber erst als zweites geschaut hätte 😉

    Grüssli



  • Hallo,
    ich konnte es leider nicht durch ein struct ersetzen, da der Compiler gemeckert hat, dass der Name bereits an anderer Stelle als Klasse auftaucht.
    Ich habe die Header-Datei "Observer.h" rausgeschmissen, die
    List<Observer*> in
    List<int*>
    umgewandelt (Zum Testen) und habe immer noch das gleiche Problem.

    ich benutze den GNU g++



  • Ich glaube eher, dass er nicht die Liste benutzt, von der er denkt, dass er sie benutzt. 😉



  • Tachyon schrieb:

    Ich glaube eher, dass er nicht die Liste benutzt, von der er denkt, dass er sie benutzt. 😉

    Zeige mal den Code für die int* Liste.



  • OK, mittlerweile sieht es so aus (Hatte aus der Liste vorhin Pointer gemacht).

    #ifndef _OBSERVABLE_H
    #define _OBSERVABLE_H
    
    #include <iostream>
    #include <list>
    
    class Observable {
    
     private:
      std::list<int*> *observers;
    
     protected:
      Observable()
        {
          observers = new std::list<int*>;
        }
    
     public:
    
      void notify(void *obj) {
    
        std::list<int*>::iterator iter = observers->begin();
        int i = 0;
        while (iter != observers->end()) {      
          std::cout << "OOO_ESTI " << i++ << std::endl;
          iter++;
        }
      }   
    
    };
    #endif
    


  • Wie legst Du denn Observable-Objekte an, wenn der Ctor protected ist?
    Falls Du von dem Ding erbst:
    Probier Observable.notify() lieber erstmal direkt in der main aus, ohne über die erbende Klasse zu gehen.



  • Tachyon schrieb:

    Wie legst Du denn Observable-Objekte an, wenn der Ctor protected ist?
    Falls Du von dem Ding erbst:
    Probier Observable.notify() lieber erstmal direkt in der main aus, ohne über die erbende Klasse zu gehen.

    Genau, ich geh momentan über die erbende Klasse. Ich habe die header-Datei in einem einfachen Testprogramm eingebunden und dort hat es eben funktioniert (aus der main aufgerufen, wie du es sagst).

    Wenn ich hier die Anzahl der Elemente ausgeben will, kommt das Programm zum Stillstand (das ist merkwürdig, oder?):

    while (iter != observers->end()) {      
          std::cout << "OOO_ESTI " << observers->size() << std::endl;
          iter++;
        }
    

    Der Konstruktor der Klasse, die von Observable erbt, sieht so aus:

    MapModel::MapModel(): Observable(){
    
    }
    

    Das habe ich doch richtig gemacht, oder?



  • Wie wird denn notify in der erbenden Klasse aufgerufen?



  • Die wird folgendermaßen aufgerufen:

    void MapModel::loadMapFile(char *filename)
    {
      ...
      notify(NULL);
    }
    

Anmelden zum Antworten