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

12.10.2014, 12:05

SDL LazyFoo tutorial - Problem bei Verwendung von Zeiger anstelle von globalen Variablen

Hallo erstmal und schönen Gruß an die Community.
Ich habe gerade angefangen die LaszyFoo SDL tutorials durchzuarbeiten und wollte nun die lästigen globalen Variablen loswerden. Also habe ich daraus kurzerhand lokale gemacht und übergebe die pointer an die entsprechenden Funktionen. Hier ist mein umgeschriebener Source Code für Lesson2. Obwohl kein Fehler vom Compiler angekreidet wird sehe ich auf diese Weise nur ein transparentes Fenster während ich unter Verwendung der globalen Variablen das zu erzeugende Bild sehen konnte. Könnte mir vielleicht jemand erklären was ich falsch gemacht habe? Ich suche nun schon seit Stunden nach der Ursache. Danke schon mal im voraus.


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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <SDL.h>
#include<stdio.h>

// #global constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

// #Prototyps
// Starts up SDL and creates window
bool init(SDL_Window* pPassedWindow, SDL_Surface* pPassedScreenSurface);

// Loads media
bool loadMedia(SDL_Surface* pPassedHelloWorld);

// Frees media and shuts down SDL
void close(SDL_Window* pPassedWindow, SDL_Surface* pPassedHelloWorld);

int main(int argc, char* args[])
{
    // The window we will be rendering to
    SDL_Window* pWindow = NULL;

    // The surface contained by the window
    SDL_Surface* pScreenSurface = NULL;

    // The image we will load and show on the screen
    SDL_Surface* pHelloWorld = NULL;

    // Start up SDL and create window
    if(!init(pWindow, pScreenSurface))
    {
        printf("Failed to initialize\n");
    }
    else
    {
        // Load media
        if(!loadMedia(pHelloWorld))
        {
            printf("Failed to load media\n");
        }
        else
        {
            // Apply the image
            SDL_BlitSurface(pHelloWorld, NULL, pScreenSurface, NULL); // SDL_BlitSurface sta,ps a copy of a source surface onto the destination surface

            // Update the surface
            SDL_UpdateWindowSurface(pWindow);

            // Wait two seconds
            SDL_Delay(2000);
        }
    }

    // Free resources and close SDL
    close(pWindow, pHelloWorld);

    return 0;
}



bool init(SDL_Window* pPassedWindow, SDL_Surface* pPassedScreenSurface)
{
    // Initialization flag
    bool success = true;

    // Initialize SDL
    if(SDL_Init(SDL_INIT_VIDEO) < -1)
    {
        printf("SDL could not initialize - SDL_Error: &s\n", SDL_GetError());
        success = false;
    }
    else
    {
        // Create window
        pPassedWindow = SDL_CreateWindow("SDL_Tutorial02", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
        if(pPassedWindow == 0)
        {
            printf("Window could not be created - SDL_Error: &s\n", SDL_GetError());
            success = false;
        }
        else
        {
            // Get window surface
            pPassedScreenSurface = SDL_GetWindowSurface(pPassedWindow); // SDL_GetWindowSurface grab the surface contained by the window
        }
    }
    return success;
}

bool loadMedia(SDL_Surface* pPassedHelloWorld)
{
    // Loading success flag
    bool success = true;

    // Load image
    pPassedHelloWorld = SDL_LoadBMP("hello_world.bmp");
    if(pPassedHelloWorld == NULL)
    {
        printf("Unable to load image &s - SDL_Error: &s\n", "hello_world.bmp", SDL_GetError()); 
        success = false;
    }
    return success;
}

void close(SDL_Window* pPassedWindow, SDL_Surface* pPassedHelloWorld)
{
    // Deallocate surface
    SDL_FreeSurface(pPassedHelloWorld);
    pPassedHelloWorld = NULL;

    // Destroy window
    SDL_DestroyWindow(pPassedWindow);
    pPassedWindow = NULL;

    // Quit SDL subsystems
    SDL_Quit();
}

2

12.10.2014, 12:34

Wo ist denn deine Gameloop?

EDIT:
Ok, sieht wie nen Test aus bei dem du 2 sec wartest.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Hannes« (12.10.2014, 12:40)


FSA

Community-Fossil

  • Private Nachricht senden

3

12.10.2014, 12:35

Du übergibst einen Zeiger und überschreibst ihn dann. Wenn musst du einen Zeiger auf einen Zeiger übergeben, und dann nur den Zeiger überschreiben:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
void bla(SDL_Window** pp)
{
    *pp = ...;
}

int main()
{
    SDL_Window* p = nullptr;
    bla(&p);
}

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

4

12.10.2014, 14:13

@FSA: Vielen Dank für die schnelle Antwort. Jetzt sehe ich den Fehler auch. Ich habe SDL_Window* pPassedWindow erst die Adresse von pWindow übergeben und dann hat in der Funktion pPassedWindow einfach die neue Adresse bekommen die eigentlich in pWindow laden sollte. :dash:
Ich danke dir für die Hilfe! Du hast mir den Sonntag gerettet.

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

5

12.10.2014, 16:01

In Modernen C++ ist übrigens nullptr dem Makro NULL vorzuziehen. Aber schon einmal sehr schön, dass du wirklich Konstanten verwendet und keine Makros dafür missbrauchst. :)
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

6

13.10.2014, 16:06

Die Methode Zeiger auf Zeiger hat bei mir leider nicht geklappt. Hab das Problem jetzt aber einfach mit einer Klasse für die SDL Komponenten gelöst.
Da ich das mit dem **Zeiger nicht kannte hab ich mir einen Artikel darüber durchgelesen. Da hieß es dass man sich das Ganze wie eine Kette vorstellen könnte. Würde das dann nicht bedeuten, dass ich nur über *p die Adresse von **p ändern kann und nicht umgedreht?

@Architekt: nullptr war mir leider noch nicht bekannt. Mir ist bisher immer nur das NULL Makro untergekommen. Hab ich das richtig verstanden, dass der Vorteil von nullptr daran liegt, dass es unabhängig vom Datentyp des Zeigers immer die dazu passende NULL-Zeiger-Konstante erstellt während NULL ja einfach nur eine 0 ersetzt?

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

7

13.10.2014, 16:59

Jap. Dadurch werden Doppeldeutigkeiten zwischen int und Zeigern verhindert.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

FSA

Community-Fossil

  • Private Nachricht senden

8

13.10.2014, 17:00

Würde das dann nicht bedeuten, dass ich nur über *p die Adresse von **p ändern kann und nicht umgedreht?

Nein. In einem Zeiger ist eine Adresse. wenn pp vom Typ Typ** ist, dann zeigt der Zeiger auf eine Adresse, welche auf einen Speicherbereich zeigt. mit *pp bekommst du die Adresse auf die pp zeigt. Wenn du die Adresse von pp ändern willst, schreibst du einfach pp = &irgendeinZeiger;

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

9

14.10.2014, 13:10

Ahh ok. Danke! Dann nehme ich nullptr gleich mal in mein Reportoire mit auf. Zu der Zeiger auf Zeiger Geschichte werde ich mir nachher am Besten mal ein kleines Programm schreiben, dass mir die Inhalte und Adressen ausgibt. Ich denke dann werde ich schon sehen/verstehen was sich genau dahinter verbirgt.

Werbeanzeige