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

03.04.2015, 23:30

Addressen von Pointern durch ein Pointer Array weiter geben

Hallo Leute ^^ ,

da ich noch recht neu im Forum bin wollte ich nur ungerne einen neuen Thread für eine solche Kleinigkeit erstellen, aber mir wurde dennoch dazu geraten es trotzdem zu tun.
Ich habe folgende Frage, undzwar setze ich mich aktuell seit kurzem mit SDL auseinander
und die Idee ist, dass ich für verschiedene Eingaben des Benutzers unterschiedliche
Bilder anzeige. Sämtliche Bilder sollen vorab geladen werden, aber dafür
muss ich ein Array aus SDL_Surface pointern an meine Funktion
übergeben. Mit einem einfachen Pointer habe ich das immer so an
Funktionen weitergereicht:

C-/C++-Quelltext

1
void funktion (SDL_Surface*& surface)


Somit konnte ich verändern, wohin der Zeiger selbst zeigt. Wenn ich nun das
selbe mit einem Array aus pointern versuche stimmt die Syntax scheinbar
nicht :| .

Falls noch nicht ganz klar ist, was genau ich versuche dort zusammen zu schreiben hier sind ein paar Codeausschnitte:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum KEY_PRESSED_STATES
{
    KEY_PRESSED_STATE_DEFAULT,
    KEY_PRESSED_STATE_UP,
    KEY_PRESSED_STATE_DOWN,
    KEY_PRESSED_STATE_LEFT,
    KEY_PRESSED_STATE_RIGHT,
    KEY_PRESSED_STATE_TOTAL_NUMBER_OF_STATES
};

int main(int argc, char* args[])
{
    SDL_Surface* surfaceMedia[KEY_PRESSED_STATE_TOTAL_NUMBER_OF_STATES] = { NULL, NULL, NULL, NULL, NULL }; // Das soll in die loadMedia funktion

    return 0;
}

bool loadMedia( Wie bekomme ich die Addresse der Elemente des Arrays hier rein ? :/ )


Ich hoffe ihr könnt einem Anfänger aushelfen :) .

Lg

Dareptor

Databyte

Alter Hase

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

2

03.04.2015, 23:40

Hi,

benutze für solche Fälle std::array.
Dann sieht das ganze folgendermaßen aus:

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
enum KEY_PRESSED_STATES
{
    KEY_PRESSED_STATE_DEFAULT,
    KEY_PRESSED_STATE_UP,
    KEY_PRESSED_STATE_DOWN,
    KEY_PRESSED_STATE_LEFT,
    KEY_PRESSED_STATE_RIGHT,
    KEY_PRESSED_STATE_TOTAL_NUMBER_OF_STATES
};

// Definiere einen array-typen
typedef std::array<SDL_Surface*, KEY_PRESSED_STATE_TOTAL_NUMBER_OF_STATES> SurfaceMediaArray;

int main(int argc, char* args[])
{
    SurfaceMediaArray surfaceMedia = { nullptr, nullptr, nullptr, nullptr, nullptr}; // Das soll in die loadMedia funktion
    loadMedia(surfaceMedia);
    return 0;
}

bool loadMedia(SurfaceMediaArray& media)
{
    media[0] = ...; // zugriff per index
}


Etwas flexibler wäre noch std::vector.

pouk_

Frischling

Beiträge: 64

Beruf: Schüler

  • Private Nachricht senden

3

03.04.2015, 23:40

Wenn du einen Pointer als Argument hast, ist es nur

C-/C++-Quelltext

1
void funktion( SDL_Surface* surface )

Also nur *
Für ein Array:

C-/C++-Quelltext

1
void funktion( SDL_Surface** surfaces )

C-/C++-Quelltext

1
2
#include <stdlib.h>
main(){for(;;malloc(1024));} // dead

4

03.04.2015, 23:55

Das war doch einfach als gedacht, danke sehr :) .

Ich habe noch 2 weitere kleine Fragen undzwar folgende:

Wann wird ein Zeiger selbst gelöscht ? Ich nehme an, dass dieser Zeiger selbst ebenfalls Speicher verbraucht ? Wenn ich nun folgendes hätte:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
SDL_Surface* loadSurface(std::string path)
{
    SDL_Surface* surface = NULL;

    surface = SDL_LoadBMP(path.c_str());

    if (surface == NULL)
        std::cout << "SDL konnte die BMP Datei nicht in den surface pointer laden. SDL_Error:\n" << SDL_GetError() << std::endl;

    return surface;
}


Würde der Zeiger surface, welcher in der loadSurface funktion erstellt wurde zerstört, oder nicht ? (Ein Memory leak sollte ja nicht stattfinden, da ich die Adresse des Inhaltes ja in einem anderen Zeiger speichere).
Und falls dies der Fall ist, warum wird dann mein Zeiger, wenn ich ihn mit:

C-/C++-Quelltext

1
void funktion (SDL_Surface*& surface)


weiter reiche nicht zerstört ? Ich glaube ich habe einen ganz doofen Denkfehler, was das freigeben von Speicher nach dem Beenden der Funktion angeht.

Meine letzte Frage ist eher SDL spezifisch. Wie genau wissen die SDL_Events, was gerade passiert ? Wie werden sie durchgehend auf dem Laufenden gehalten ? Wie kann es sein, dass

C-/C++-Quelltext

1
while( SDL_PollEvent( &e ) != 0 )


Nicht durchgehend > 0 ist, wenn es doch bei jeder Abfrage ein Event erhält.

Auch auf die Gefahr hin mich hier total lächerlich zu machen hoffe ich, dass die Fragen nicht ganz bescheuert sind :rolleyes: .

Danke vielmals für eure hilfe (Ich hatte eine recht lange Pause vom Programmieren und habe scheinbar doch so einiges wieder vergessen ?( ).

Lg

pouk_

Frischling

Beiträge: 64

Beruf: Schüler

  • Private Nachricht senden

5

04.04.2015, 00:03

Das Eventsystem wird hier schöner erklärt als ich könnte : http://lazyfoo.net/SDL_tutorials/lesson04/index.php

Ein SDL_Surface kann mit SDL_FreeSurface( SDL_Surface* surface ) gelöscht werden. ( [url]http://wiki.libsdl.org/SDL_FreeSur…tegoryStruct%29[/url] )

C-/C++-Quelltext

1
2
#include <stdlib.h>
main(){for(;;malloc(1024));} // dead

6

04.04.2015, 00:10

Das habe ich mir soweit durchgelesen, aber woher bekommt mein:

SDL_Event event;

seine Informationen ? Ich update das Event selbst ja nie in meinem Code sondern reiche nur seine Informationen weiter.
Das die SDL_Surface mit SDL_FreeSurface gelöscht werden kann ist mir ebenfalls bewusst, aber wann wird der Pointer selbst denn zerstört ? Müsste das nicht wie bei allen normalen Variablen am Ende der Funktion der Fall sein, da sonst jeder Zeiger ein Memory leak wäre, sobald er nicht mehr verwendet wird ? (Nicht um den Inhalt geht es mir, sondern um den Zeiger selbst)

pouk_

Frischling

Beiträge: 64

Beruf: Schüler

  • Private Nachricht senden

7

04.04.2015, 00:16

SDL_LoadBMP liefert einen Zeiger auf einen Surface zurück, der bei deinem Fall in "surface" gespeichert wird. "surface" wird am Ende der Funktion zerstört und du kannst den Inhalt nicht mehr erreichen. Variablen in Funktionen werden auf dem Stack angelegt und falls die Funktion endet werden die Variablen im Stack "gelöscht".

C-/C++-Quelltext

1
2
#include <stdlib.h>
main(){for(;;malloc(1024));} // dead

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

8

04.04.2015, 00:18

Dein Event bekommt seine Informationen vom darunter liegenden Betriebssystem. Sobald du deine Maus bewegst, eine Taste drückst oder sonst etwas, dann wird das SDL Event System darüber informiert und teilt seine Informationen mit dir. SDL_PollEvent "zieht" diese Information aus der globalen Liste der ankommenden Events und verringert diese somit jedesmal. Aber wenn du nichts machst, das Fenster nicht anklickst, keine Tastatureingabe machst etc., dann wird auch kein Event "abgefeuert".

Der Pointer wird nicht zerstört, sondern der Inhalt auf den er eben zeigt. Ein Pointer kann lediglich ungültig werden. Er belegt 4 bzw. 8 Bytes auf dem jeweiligen Stack und zeigt nur auf einen Bereich im Heap. Mit SDL_FreeSurface wird der Speicher freigegeben, auf den deine SDL_Surface zeigt.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

9

04.04.2015, 00:28

Naja also den Inhalt kann ich ja noch erreichen, da ich durch das Return die Adresse der Variable an meinen Zeiger weiterreiche, welche zum Aufruf dieser Funktion benötigt wird.

Beispiel

C-/C++-Quelltext

1
2
3
4
5
std::string Datenpfad = "123";

SDL_Surface* surface = NULL;

surface = loadSurface (Datenpfad); // surface müsste doch dem Memory leak vorbeugen, oder nicht ?


Nun falls es so ist, wie du es gerade beschrieben hast, dass die Zeiger nach dem Beenden der Funktion zerstört werden, warum habe ich dann noch Funktionen mit meinen Zeiger durchführen können, nachdem ich die Position verändert habe auf welche sie zeigen ? Werden die Zeiger selbst nur nach dem Abschluss der Funktion zerstört in der sie selbst erstellt wurden ?

C-/C++-Quelltext

1
2
3
4
void loadInSurface (SDL_Surface*& surface, std::string Datenpfad)
{
    surface = SDL_LoadBMP(Datenpfad.c_str());
}

Und an Architekt, also kümmert sich SDL_PollEvent, dass das Event nicht mehr als aktuell angesehen wird ? Und falls ja wie genau macht es das ?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Dareptor« (04.04.2015, 00:33)


pouk_

Frischling

Beiträge: 64

Beruf: Schüler

  • Private Nachricht senden

10

04.04.2015, 00:35

Ja, die Zeiger wird nur nach Abschluss der Funktion, in der sie deklariert worden ist, zerstört. Auf was sie zeigt kann sich beliebig oft verändern.

C-/C++-Quelltext

1
2
#include <stdlib.h>
main(){for(;;malloc(1024));} // dead

Werbeanzeige