for vs. for each



  • Hallo,
    Ich habe ein Problem mit einer for each Schleife.
    Diese stürzt bei Ausführung als Release in der ersten Zeile ab.
    Als Debug funktioniert alles einwandfrei. Auch die Werte stimmen.

    Der Code wird in einer Funktion eines Objektes Ausgeführt.

    for each (HwType type in hardwareInfo.setup)//in dieser Zeile stürzt er ab
    {
    	config.addChannel(type.Value).enabled);
    }
    

    hardwareInfo ist vom Typ CCHardwareInfo und ist ein private Attribut des Objekts, in dem auch die Funktion ausgeführt wird.

    hardwareInfo und HwType sind wie folgt in einer header definiert:

    class CCHardwareInfo
    {
    public:	
    	bool save;	//save setup
    	bool reload;	//reload setup
    	vector<hwType> setup;
    	string ident;	//Identstring
    };
    
    struct HwType
    {
    	HwType(short Id)
    	{
    		typeId   = Id;
    		value	 = 0;
    		currency = 0;
    	}
    
    	short		typeId;	
    	unsigned long	value;	
    	short		currency;
    };
    

    Ersetze ich die for each-Schleife durch eine for-Schleife in folgender Weise
    funktioniert es einwandfrei. Wie kann das sein?

    for(int i=0; i<hardwareInfo.setup.size(); i++)
    


  • Es gibt keine for each Schleife in C++.



  • Abgesehen von dem for each, was es nur beim Microsoft-Compiler gibt, ist dein Code syntaktisch falsch, vermutlich Tippfehler. hwType vs. HwType, falsche Klammerung, vielleicht noch mehr? Auf der Basis kann man kaum erkennen, was das Problem sein könnte.



  • Und vor allem passt der Code hinten und vorne nicht zusammen:
    1.- ist das kein privater Member der Klasse in der die Funktion ist, wie du sagst.
    2.- Bei der "normalen" For Schleife sagst du irgendwas von billSetup, das ist da aber nicht definiert/deklariert.

    Zu deinem Problem:
    Die Range-Based For Schleife aus C++ setzt auf begin() und end() auf. Das bedeutet im Umkehrschluss, sie kann niemals ausserhalb der Arraygrenzen zugreifen, da du auf den eigentlichen Iterator nichtmals Zugriff hast (was ja auch gut so ist).

    vector<int> vec = { ... };
    
    for(int i : vec) // oder int & i, oder const int& oder oder)
    {
         i += 10; // kann niemals schiefgehen
    }
    

    Problematisch wird das mit Zeigern:

    vector<int> * vec = getVector();
    
    for(int i : *vec)
    {
        i += 10;
    }
    

    Denn was ist, wenn die Funktion in dem Beispiel einen nullptr zurückgibt?
    Richtig Absturz, gewöhnlich.

    Wenn das bei dir ausgeschlossen sein sollte, dann hast du an ganz anderer Stelle Fehler gemacht (z.B. einen nullptr aus einer Funktion bekommen und damit gearbeitet, aber deine IDE hat den Fehler nicht gemeldet)



  • Es gibt keine for each Schleife in C++.

    Also eigentlich schon (zumindest mit _) http://www.cplusplus.com/reference/algorithm/for_each/ 😃



  • tröröö schrieb:

    Es gibt keine for each Schleife in C++.

    Also eigentlich schon (zumindest mit _) http://www.cplusplus.com/reference/algorithm/for_each/ 😃

    Hast du heute noch nicht genug dummes Zeug geschrieben?



  • Machst du oft Einträge, die absolut echt null Inhalt haben? Dir ist schon klar, dass dein letzter Eintrag nur Spam war, oder? Wenn du es besser weißt, schreibs rein. Und vor allem: da brichst du dir nichts ab, dich in einem Forum zu registrieren.



  • Du wirst doch wohl kein using namespace std im Header haben? Das ist ganz böse. Im Header solltest Du immer mit voll qualifizierten Namen wie std::vector und std::string arbeiten. Der Einheitlichkeit halber empfehle ich das auch im cpp. Aber da gehen die Meinungen auseinander.


  • Mod

    Im Header solltest Du immer mit voll qualifizierten Namen wie std::vector und std::string arbeiten.

    Nö, im Header schreibst du die using -Direktive einfach in die Funktionen rein.



  • Arcoth schrieb:

    Im Header solltest Du immer mit voll qualifizierten Namen wie std::vector und std::string arbeiten.

    Nö, im Header schreibst du die using -Direktive einfach in die Funktionen rein.

    Manchmal nervt deine Spitzfindigkeit einfach nur. Der Ratschlag von tntnet ist schon ganz gut, er schreibt ja auch man sollte, nicht man muss. Das lässt Spielraum für Sonderfälle, z.B. wenn man im Header tatsächlich Funktionen implementiert statt sie nur zu deklarieren. Und erklär´ mir bitte doch mal, wie man using namespace std; oder using std::string für folgende Funktion einsetzen soll:

    std::string do_something( SomeType MyType )
    {
       ...
    }
    

  • Mod

    Edit: Gut, das war offensichtlich zu spitzfindig.



  • Hallo,
    Hatte leider 2 Fehler im Code, habe ich jetzt behoben. in der for-Schleife muss es natürlich auch setup sein und nicht billSetup. Und der Construktor soll HwType heißen.

    Ich habe den Code möglichst kurz gehalten, damit man nicht unnötig viel lesen muss.

    hardwareInfo ist ein private Member der Klasse in der die Funktion ausgeführt wird.
    ich kann auch in der Funktion darauf zugreifen, habe ich ausgiebig getestet.



  • Das mit

    using namespace std
    

    hatte ich allerdings. War aber nicht die Ursache..


Log in to reply