Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

26.07.2009, 18:53

list iterator not dereferencable

Mir ist leider nicht ganz klar, was mir diese Fehlermeldung sagen möchte.

Expression: list iterator not dereferencable

Ich hab ein bisschen gegoogelt und glaube die Bedeutung herrausgefunden zu haben, dass es sich hier darum handelt, das man eine leere Liste nicht durchlaufen lassen kann.
Jedoch habe ich meiner Meinung nach die Möglichkeit ausgeschlossen, dass leere Listen durchlaufen werden, indem ich eine while-Schleife davorgesetzt habe, wie es mir schon beim Rendern der Schüsse vorgemacht wurde.
Trotzdem erscheint weiterhin diese Fehlermeldung.

Hier ein paar Codeausschnitte:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void CGame::RenderExplosions ()
{
    //Iterator für Explosionsliste

    list<CExplosion>::iterator It = m_ExplosionList.begin ();


    while (It != m_ExplosionList.end ())
    {
        //Explosion updaten

        It->Update ();

        //Ist der Schuss noch aktiv?

        if (It->IsAlive ())
        {
            //Ja,dann rendern

            It->Render ();
            It++;
        }
        else
        {
            //Nein, dann aus der Liste entfernen

            It = m_ExplosionList.erase (It);
        }
    }

}//RenderExplosions


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
void CGame::CheckCollisions ()
{
    //Schussliste des Spielers holen

    list<CShot> *ShotList = m_pPlayer->GetShotList ();

    //Iteratoren für Asteroiden-, Explosions- und  Schussliste

    list<CAsteroid>::iterator ItAsteroid = m_AsteroidList.begin ();
    list<CExplosion>::iterator ItExplosion;
    list<CShot>::iterator ItShot;

    //Rects für Asteroiden und schüsse

    SDL_Rect RectAsteroid;
    SDL_Rect RectShot;

    //Alle Asteroiden durchlaufen

    while (ItAsteroid != m_AsteroidList.end ())
    {
        //Rect des Asteroiden holen

        RectAsteroid = ItAsteroid->GetRect ();

        //Alle Schüsse durchlaufen

        for (ItShot = ShotList->begin ();
             ItShot != ShotList->end ();
             ++ItShot)
        {
            //Rect der Schüsse holen

            RectShot = ItShot->GetRect ();

            //Überschneiden sich die Rects?

            if (RectShot.y < RectAsteroid.y + RectAsteroid.h - 15.0f &&
                RectShot.y + RectShot.h - 15.0f > RectAsteroid.y &&
                RectShot.x < RectAsteroid.x + RectAsteroid.w - 15.0f &&
                RectShot.x + RectShot.w - 15.0f > RectAsteroid.x)
            {
                //Ja, also gab es eine Kollision.

                //Neue Explosion erstellen

                CExplosion Explosion;
                //Explosion ersetzt Asteroiden

                ItExplosion->Init (m_pSpriteExplosion, ItAsteroid->GetXPos (), ItAsteroid->GetYPos ());
                //Explosion in Liste einordnen

                m_ExplosionList.push_back (Explosion);
                //Schuss und Asteroiden deaktivieren

                ItAsteroid->SetAlive (false);
                ItShot->SetAlive (false);
            }
        }

        //Asteroid löschen, falls deaktiviert

        if (ItAsteroid->IsAlive ())
            ItAsteroid++;
        else
            ItAsteroid = m_AsteroidList.erase (ItAsteroid);
    }
} //CheckCollision


Bedanke mich schonmal für die Hilfe

koschka

Community-Fossil

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

2

26.07.2009, 19:10

Es liegt an dem löschen. (erase)

Du kannst keine Elemente löschen, während du auf der Liste operierst.

Programm, das den Fehler generiert:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <list>

int main()
{
    std::list<unsigned> aList;

    aList.push_back(3);
    aList.push_back(4);
    aList.push_back(5);

    //Iterator

    std::list<unsigned>::iterator it = aList.begin ();


    while (it != aList.end ())
    {
        it++;

        if(*it == 4)
        {
            //Nein, dann aus der Liste entfernen

            it = aList.erase (it);
        }
    }
}


Lösung:
Speichere die zu löschenden Elemente in eine seperate Liste!

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

3

26.07.2009, 19:15

Und ob das erlaubt ist. Du machst es einfach falsch..

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <list>

int main()
{
    std::list<unsigned> aList;

    aList.push_back(3);
    aList.push_back(4);
    aList.push_back(5);

    //Iterator

    std::list<unsigned>::iterator it = aList.begin ();


    while (it != aList.end ())
    {
        if(*it == 4)
        {
            //Nein, dann aus der Liste entfernen

            it = aList.erase (it);
        }
        else
         ++it;
    }
}


Warum machst du eine überprüfung und invalidierst dann den, indem du den Iterator sofort wieder inkrementierst? - Schon klar gibt es den Fehler..

@RaC++er
Probier mal rauszufinden, wo genau dieser Fehler auftritt. Wo behandelst du denn das löschen der Schüsse?

4

26.07.2009, 19:33

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void CPlayer::Render ()
{
    // Position des Spielers setzen und Sprite rendern

    m_pSpritePlayer->SetPos (m_fXPos, m_fYPos);
    m_pSpritePlayer->Render (m_fAnimPhase);

    //Iterator für Schussliste

    list<CShot>::iterator it = m_ShotList.begin ();

    //Schussliste durchlaufen

    while (it != m_ShotList.end ())
    {
        //Schuss updaten

        it->Update ();

        //Ist der Schuss noch aktiv?

        if (it->IsAlive ())
        {
            //Ja,dann rendern

            it->Render ();
            it++;
        }
        else
        {
            //Nein, dann aus der Liste entfernen

            it = m_ShotList.erase (it);
        }
    }
}// Render


Hier werden die Schüsse gelöscht. Daher wollte ich die Explosionen genauso behandeln, was wiederum nicht klappt.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

5

26.07.2009, 19:49

Du weisst dem ItExplosion gar kein Element zu.

Hier crasht es:

C-/C++-Quelltext

1
                ItExplosion->Init (m_pSpriteExplosion, ItAsteroid->GetXPos (), ItAsteroid->GetYPos ()); 


Wobei ich nicht ganz verstehe, was du da eigentlich machst, aber du weit ItExplosion auf jeden Fall keinen gültigen Iterator zu..

6

26.07.2009, 19:56

Ok ohne Iterator klappt es (Also statt ItExplosion nur Explosion)
Danke für die Hilfe

@drako:Ja ich verstehe mich grade auch nicht selber^^

Werbeanzeige