Vector Erase Iterator Outside Range



  • std::vector<unsigned char*> ImgData;
    
    void imageStorageClass::setImage(unsigned char* imgData)
    {
    
    	// Nach 5 Bilder im Puffer wird das älteste [0] verworfen und das neuste [4] hinten rangehängt (FIFO Prinzip)
    	if((int)this->ImgData.size() == 5)
    	{
    		delete [] ImgData[0];	
    		ImgData.erase(ImgData.begin());  //DEBUG ASSERTATION FAILED;
    		this->currentImage = this->ImgData[(int)this->ImgData.size()-1];
    		this->lastImage = this->ImgData[(int)this->ImgData.size()-2];
    	}
    	else
    	{
    		this->ImgData.push_back(imgData);
    		this->currentImage = this->ImgData[(int)this->ImgData.size()-1];
    		if((int)this->ImgData.size() > 1)
    		{this->lastImage = this->ImgData[(int)this->ImgData.size()-2];}
    		else
    		{this->lastImage = this->currentImage;}
    	}
    	this->TotalImageSaved++;
    
    }
    

    Hi, ich habe eine komisches Problem und weiß mir nicht mehr zu helfen.
    Ich entwickle derzeit ein Programm welches einen Bildstream codiert. Dazu habe ich einen Vector eingerichtet der mir die Speicheradressen zu den letzten 5 Bilder speichert. Wenn 5 Bilder im Vector sind soll immer das älteste gelöscht werden und das neueste wird hinzugefügt.

    Das Speicher frei geben funktioniert noch einwandfrei, wenn ich aber darauf hin den Befehl ImgData.erase(ImgData.begin()); aufrufe, bekomme ich eine Debug Assertation Failed meldung.

    Woran kann das liegen? Im Release Modus funktioniert das ohne Fehlermeldung. Aber es muss ja einen Grund geben, warum das so ist.

    Gruß


  • Mod

    Das kann irgendwie nicht sein. Kannst du ein minimales, compilierbares Beispiel produzieren, an dem man das nachvollziehen kann? Dass die Assertion nur im Debugmodus geworfen wird liegt übrigens da dran, dass es der Debugmodus ist 🙂 . Das ist ja gerade der Punkt, dass dort Assertions aktiviert sind, im Releasemodus wird dein Programm stillschweigend Fehler machen und vielleicht später abstürzen, vielleicht auch nicht, ist halt undefiniertes Verhalten.

    Was allgemein auffällt:
    Was sollen die ganzen C-Casts oder allgemein die Casts? Dadurch provozierst du gerade zu, dass Fehler im Code vom Compiler nicht entdeckt werden. Vielleicht hast du auf diese Weise einen Fehler an früherer Stelle verdeckt.
    Was sollten die ganzen this-> ?
    Wenn man new[] oder delete[] benutzt, dann macht man etwas falsch. new und delete mag man manchmal ja noch brauchen, aber dynamische Arrays braucht man in C++ nun wirklich nie von Hand machen. Das provoziert auch nur Fehler. Eventuell ist dein Fehler auch darauf zurück zu führen.

    Wenn ich wetten müsste, würde ich auf Fehler bei deiner unnötigen manuellen Speicherverwaltung setzen. Das darauf folgende undefinierte Verhalten hat manchmal so lustige Folgen wie diese hier.



  • Danke für die schnelle Hilfe.

    Ich habe jetzt mal ein kleines Programm geschrieben das genau das macht, was das große auch soll. Und komischer weiße funktioniert es dort mit der Speicherung und löschung genauso wie es soll. Dabei habe ich nix an meine ImageStorage Class geändert.

    Die Cast sind/waren nur da um die Compilerwarnungen bei der Typkonvertierung zu vermeiden. Allerdings werden die Warnungen bei dem Testprogramm auch nicht mehr angezeigt. Die this-> Pointer ruf ich auf damit ich auf dem 1. Blick sehe welche Variable global und welche lokal ist in der jeweiligen klasse.

    Ist dieses Verhalten den verkehrt?

    Wenn man new[] oder delete[] benutzt, dann macht man etwas falsch. new und delete mag man manchmal ja noch brauchen, aber dynamische Arrays braucht man in C++ nun wirklich nie von Hand machen. Das provoziert auch nur Fehler.

    Wenn ich ein Speicher für mein Bild reserviere mache ich das so:

    unsigned char* tmp = new unsigned char[IMG_ROWS*IMG_COLS];
    

    und das ganze gebe ich doch dann wieder mit

    delete [] tmp;
    

    frei oder ist das vekehrt?

    Ich suche jetzt das andere Programm nach dem Fehler ab 😃
    Wünscht mir Glück 😉


  • Mod

    Wenn ein Compiler dich warnt, hat er im Allgemeinen Recht. Mit einem C-Cast dem Compiler zu sagen, dass er das Maul halten soll, ist ein gefährlicher Weg.

    Deine Speicherverwaltung kann man nur am Gesamtprogramm als richtig oder falsch einschätzen. Es bleibt die Feststellung, dass new[] und delete[] äquivalent zur Nuztung eines vectors sind, bloß dass beim vector nichts schiefgehen kann.



  • Warum nimmst du nicht einfach statt dessen ein

    std::vector<std::vector<unsigned char> > ImgData;
    

    Dann fällt das ganze new und delete flach.



  • Sofern du nicht häufig einzelne Zeilen oder Spalten entfernst, würde ich einen eindimensionalen Vektor nehmen und eine Funktion für 2D-Zugriff schreiben.


Anmelden zum Antworten