Zugriffverletzung mit STL vector



  • Und mit welchen Werten initialisierst du mapwidth und mapheight ? 😉



  • mapwidth und mapheight sind globale short int die mit dem Laden der Map initialisiert werden, mit meiner aktuellen Map sind beide Werte je 100.
    Aber guter Hinweis, dass ich darauf achten muss, diese vorher zu initialisieren habe ich fast missachtet (ist aber trotzdem geschehen...). 👍



  • Kannst du mit dem Debugger eventuell noch etwas den Stack hochwandern in deinen eigenen Quelltext?



  • Also der Fehler entsteht schon beim Aufruf von

    DynamiteList.clear();
    

    Das ganze ist mir unerklärlich!?



  • for( iter i = DynamiteList.begin(); i != DynamiteList.end(); ++i)
            {
                (*i).Blit( dest, mxo, myo);
                if( (*i).Explode())
                {
                    DynamiteList.erase( i, i);               
                }
            }
    

    In diesem Fall würdest du der Iteration unter dem Hintern die Elemente wegziehen, ist das so legal? Allerdings bringt das erase so nix, denn die beiden Iteratoren sollten eine Sequenz bilden und die ist in diesem Fall leer.
    Edit: Aber erase gibt den ersten gültigen iterator nach der gelöschten Sequenz zurück, den könntest du für den nächsten Durchlauf nutzen oder den alten Iterator inkrementieren, falls nix explodiert ist.



  • Also wenn das clear zum Absturz führt, ist dein DynamiteMgr nicht initialisiert... Dann liegt das momentane Absturzproblem außerhalb von CDynamiteMgr. Immerhin ist diese Anweisung die allererste die überhaupt auf die Daten des Objekts zugreift.



  • olli11 schrieb:

    Also der Fehler entsteht schon beim Aufruf von

    DynamiteList.clear();
    

    Das ganze ist mir unerklärlich!?

    Dann wäre (insbesondere der Destruktor von) CDynamite (incl.
    Copy-Construktoren) mal interessant...



  • Vielen Dank erstmal allen, die mir helfen wollen!

    @Decimad
    Du hast wohl recht, diese for-Schleife muss ich wohl noch mal überarbeiten. Aber wie lösche ich denn ein einzelnes Objekt aus der Liste?

    EIn Auszug aus CDynamite:

    CDynamite()
    	:	Active( 0),
    		Type( 0),
    		Time( 0),
    		X( 0),
    		Y( 0)
    	{
    		//BmpDynamite = load_bitmap( "dynamite.tga", NULL);
    	}
    
    	~CDynamite()
    	{
    		//destroy_bitmap( BmpDynamite);
    	}
    	void Reset()
    	{
    		Active = 0;
    		Type = 0;
    		Time = 0;
    		X = 0;
    		Y = 0;
    	}
    
    	void Blit( BITMAP* dest, int mxo, int myo)
    	{
    		if( Active)
    		{
    			char fpstext[8];
    			sprintf (fpstext, "%d", Time) ;
    			text_mode (0);
    			textout (dest, font, fpstext, X -mxo +10, Y -myo +10, 255);
    			//masked_blit( BmpDynamite, dest, 0, 0, X -mxo, Y -myo, BmpDynamite->w, BmpDynamite->h);
    			Time--;
    		}
    	}
    
    	bool Explode()
    	{
    		if( !Time)
    		{
    			if( Type == 1 || Type == 3 || Type == 4)
    			{
    				// ...
    			}
    			if( Type == 2 || Type == 3 )
    			{
    				// ...
    			}
    			if( Type == 4)
    			{
    				// ...
    			}
    			Active = false;
    			return 1;
    		}
    		return 0;
    	}
    
    	void Activate( int type, int x, int y)
    	{
    		X = x; Y = y;
    		Type = type;
    		Time = 3 * 60;
    		Active = true;
    	}
    //...
    	bool Active;	// aktiv, d.h. gezündet
    	char Type;		
    	char Time;		// verbleibende Zeit bis zur Explosion
    	int X, Y;		// Position in Map
    	//BITMAP *BmpDynamite;	// die Bitmap-Grafik
    

    Es ist jedoch egal, ob ich BmpDynamite herausnehme oder nicht!

    Dann liegt das momentane Absturzproblem außerhalb von CDynamiteMgr

    Wie kann es dann sein, dass der Fehler nur mit (vollständigem) CDynamiteMgr auftritt?
    Oder besser gefragt: Wo meinst du kann der Fehler sonst liegen?



  • Also ich steige im Moment nicht durch diesen Quelltext bzw. verstehe den Bezug nicht zu dem vorhergehenden, kann nirgendwo etwas von wegen DynamiteMgr lesen. Was ich meinte ist, dass Init und somit std::list::clear ja überhaupt nur aus dem Konstruktor von DynamiteMgr aufgerufen wird. Wenn ein clear von einer Default-Konstruierten std::list mit Ausnahme aussteigt, dann muss da vorher schon etwas arg im Argen gelegen haben. Zumindest meiner außenstehenden Ansich nach, im Moment.
    Also, debugge das Programm, beim Crash gehe per Debugger im Stackfenster so weit hoch dass du irgendwann in deinem Quelltext landest und dann noch weiter hoch, bis du etwas unerwartetes entdecken kannst. Das wird man wahrscheinlich schon in Init sehen, wenn der this-Zeiger krumm ist, dann kann man noch weiter hochgehen und schauen, warum dem wohl so ist.

    Da ich mich heute an anderer Stelle mit dem Thema Remote-Unterstützung bzw. RDP beschäftigt habe, kommen mir jetzt immer die Gedanken, dass man als Außenstehender ja eigentlich fix per RDP dein Visual-Studio fernsteuern könnte, um den Fehler zu finden etc bzw. fix den Source-Code zu brausen 😃



  • Ach ich Dummchen 🙄 - habe Init von DynamiteMgr aufgerufen bevor ich die Instanz selbst erstellt habe. *Rot-werd*-Smiley
    Der Fehler ist also damit behoben.
    Vielen Dank euch!



  • olli11 schrieb:

    Ach ich Dummchen 🙄 - habe Init von DynamiteMgr aufgerufen bevor ich die Instanz selbst erstellt habe.

    Würdest du nicht so eine C-Style-Objektsemantik mit öffentlichen Init-Funktionen betreiben, könntest du Probleme dieser Art auch besser in den Griff kriegen. Verwende Konstruktoren zur Objektinitialisierung. Die Container am Anfang zu leeren macht übrigens auch nicht viel Sinn. Sollte die Init() -Funktion mehr als einmal aufgerufen werden, nenn sie anders.

    Und halte dich bei der Gelegenheit auch an die Regel der Grossen Drei: Sobald eine der Methoden Kopierkonstruktor, Zuweisungsoperator und Destruktor implementiert wird, müssen die anderen beiden ebenfalls vom Benutzer definiert werden. Und nimm statt int type ein enum mit allen Typen, damit sparst du dir Magic Numbers und ihre Probleme, zudem wird der Code übersichtlicher.



  • und nur so btw:

    for( iter i = DynamiteList.begin(); i != DynamiteList.end(); ++i)
            {
                (*i).Blit( dest, mxo, myo);
                if( (*i).Explode())
                {
                    DynamiteList.erase( i, i);               
                }
            }
    

    =>

    iter i = DynamiteList.begin();
    while(  i != DynamiteList.end())
    {
        i->Blit( dest, mxo, myo);
        if( i->Explode())
        {
            i = DynamiteList.erase( i);               
        }
        else
        {
            ++i;
        }
    }
    

Anmelden zum Antworten