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

20.08.2014, 21:30

Kapitel 12 SDL - Fehler im Listing ?!

Halli hallo,

ich hab mir vorhin das Listing zum Spiel, aus Kapitel 12, in Visual Studio eingefügt. Jedoch stürzt das Programm nach dem Start sofort ab. Im Debug-Modus bekomme ich dann folgenden fehler

(Link)


Der fehler scheint in der KeyDown-Funktion zu liegen da wenn ich dort ein return(true/false) mache geht alles bis auf das er nicht auf eingaben reagiert was ja auch logisch ist.
Was mir komisch vorkommt da der Fehler ja durch zugriff auf nicht zulässigen Speicherplatz hervorgerufen wird, oder ?

C-/C++-Quelltext

1
2
3
4
5
6
7
bool CFramework::KeyDown (int Key_ID)
{
    // Prüfen, ob Taste gedrückt ist
    return (m_pKeystate[Key_ID] ? true : false);
    //return (true);

}


Jemand ne Ahnung woran es liegen kann ?

2

20.08.2014, 21:55

Richtig, der Fehler wird durch einen Zugriff auf nicht allokierten Speicher hervorgerufen. D.h. m_pKeystate wird zu zeitig deleted. D.h. wiederum, dass der coseausschnitt nicht reicht, um den Fehler zu finden.
Entweder du debugst das selbst, indem du einen datenhaltepunkt setzt, oder du schaust nochmal, was du an dem listing selbst geändert hast und teilst uns das mit. Ich kann mir kaum vorstellen, daß im Buch solch ein Fehler steht ;)
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

3

20.08.2014, 22:02

Habe am Listing selbst nichts geändert, werde aber gleich nochmal nachschauen was es mit m_pKeystate auf sich hat


EDIT: Habe das eben mal nachgesehen und kann leider selber keinen Fehler finden. m_pKeystate bekommt im Init-Prozess den Pointer auf das KeyState-Array welches durch PumpEvents geupdatet wird
somit verstehe ich nicht, warum er da rummeckert. Außer ich habe die SDL falsch eingebunden aber dann dürfte der rest ja nicht laufen. :search: :search:

Habe Win 8.1 mit VS 2013 Premium falls es daran liegen könnte :P

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Qube« (20.08.2014, 22:21)


4

20.08.2014, 22:39

Ich vermute einfach mal, dass du eine andere Version von sdl nutzt, als im Buch verwendet wird. Ich habe das Buch selber nicht, sodass ich da nicht im Quelltext selber schauen könnte.

Du solltest aber wie gesagt mal einen datenhaltepunkt setzen auf den Wert des Speicherbereichs, auf den der genannte pointer zeigt. Im debug Modus setzt Visual studio den Speicher bei einem dealloc auf 0xCD. Am Haltepunkt angelangt solltest du uns dann hier den callstack mitteilen.

Mit deinem Visual Studio hat das nichts Zutun.
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

5

21.08.2014, 13:07

Das mit dem Datenhaltepunkt hat nicht Funktioniert, desswegen hab ich einfach einen manuellen Haltepunkt bei der kritischen Abfrage gesetzt.
Das ganze sieht folgender Maßen aus.


(Link)


Was mir auffällt ist, dass obwohl ich keine Taste gedrückt habe der einen Wert für Key_ID hat. Ist das der Defaultwert oder irgendwas, was nicht stimmt ?

6

21.08.2014, 16:05

Du scheinst über die Grenzen des Arrays hinaus zu schießen.
Wo kommt denn der Wert der Variable Key_ID her? Was steht in den Codezeilen von CPlayer::ProcessMoving() und CPlayer::Update()?
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

7

21.08.2014, 16:16

Update() ruft lediglich ProcessMoving() auf

Und wenn ich das richtig verstehe gibt ProcessMoving lediglich an die KeyDown-Funktion ein Parameter einer Taste weiter und die checkt dann ob diese im Array vorhanden ist

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
void CPlayer::ProcessMoving ()
{
    // Nach links?
    if (g_pFramework->KeyDown (SDLK_LEFT))
    {
        // Spieler nach links bewegen
        m_fXPos -= 300.0f * g_pTimer->GetElapsed ();

        // Animieren
        m_fAnimPhase -= 20.0f * g_pTimer->GetElapsed ();

    }
    // Nach rechts?
    else if (g_pFramework->KeyDown (SDLK_RIGHT))
    {
        // Spieler nach rechts bewegen
        m_fXPos += 300.0f * g_pTimer->GetElapsed ();

        // Animieren
        m_fAnimPhase += 20.0f * g_pTimer->GetElapsed ();

    }
    // Spieler wurde nicht bewegt
    else
    {
        // Animation zurück zum Ausgangspunkt
        if (m_fAnimPhase > 5.0f)
            m_fAnimPhase -= 20.0f * g_pTimer->GetElapsed ();
        if (m_fAnimPhase < 5.0f)
            m_fAnimPhase += 20.0f * g_pTimer->GetElapsed ();
    }
}

8

21.08.2014, 21:41

Sehr seltsam. Jetzt wird's kompliziert. Key_ID ist korrekt und laut deinem Debugger-Screenshot zeigt m_pKeystate auch noch auf richtigen Speicherbereich. Außerdem ist dein gecalltes Objekt (this / g_pFramework) scheinbar valid.

Wo und wie initialisierst du m_pKeystate?
Wie groß ist das Array (Du kannst der SDL_GetKeyState() Funktion einen Pointer auf einen signed int als Parameter übergeben, in welchen die Größe gespeichert wird)?
In welcher Zeile genau gibt es die Fehlermeldung?

Interessant wäre ein Screenshot, nachdem du bei der Fehlermeldung auf "Unterbrechen" geklickt hast

Zitat

Was mir auffällt ist, dass obwohl ich keine Taste gedrückt habe der einen Wert für Key_ID hat.
Kein Wunder, wenn du der Funktion eine Konstante übergibst: g_pFramework->KeyDown (SDLK_LEFT)

Zitat

und die checkt dann ob diese im Array vorhanden ist
Nicht, ob sie im Array vorhanden ist, sondern die Funktion gibt je nachdem welchen Wert (0 oder 1) das Array an gegebener Stelle hat und gibt je nachdem true oder false zurück.
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

9

22.08.2014, 22:06

Wie sagte mein C++ Dozent immer: "Der Fehler sitzt immer vor dem Rechner!"

Ich hab das Projekt nochmal komplett neu in VS eingebunden und siehe da, ES GEHT. :crazy:
Jedoch geht weder das schießen noch die Kollisionsabfrage aber ich glaub das ist nur ne Sache des Codes :D

Trotzdem danke für die Hilfe und falls du nach dem Fehler suchen willst ist hier ein Link zum Projekt: https://www.dropbox.com/s/tlb3pymq8vpyjmx/SDL_Game.zip?dl=0

TigerClaw25

unregistriert

10

24.07.2017, 15:15

Das Thema ist schon etwas älter, aber warum wird "const uint8 *m_pKeystate;" überhaupt als Array im Buch bezeichnet? Meine Frage:
Ist das nicht ein Zeiger? Da es als Array bezeichnet wird, was ja indirekt nicht falsch ist, bedeutet, dass mehrere Tasteneingaben darin gespeichert werden können?

Meiner Meinung nach hätte man es als "Zeiger auf ein Array mit Key-states" bezeichnen sollen. Und was genau beinhaltet dieses Array? Mehrere Staten? Warum nicht immer das aktuellste?

Was mich außerdem irritiert ist m_pKeystate[Key_ID]. Key-ID ist ja keine Zahl in der SDL. Wie erfolgt dann der Zugriff? Oder sind z.B. "SDL_SCANCODE_RIGHT" oder "SDL_SCANCODE_SPACE" einfach nur enums, das heißt:
m_pKeystate[SDL_SCANCODE_RIGHT] ? true ist das gleiche wie beispielsweise
m_pKeystate[2] ? true ???

Das würde dann bedeuten, ich habe ein Array, jede Taste ist über enum einer Zahl, also einem Index zugeordnet und jeder Eintrag im Array hat entweder true oder false, korrekt?

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »TigerClaw25« (24.07.2017, 16:03)


Werbeanzeige