SDL3_package : Welche Resourcen muss ich manuell freigeben mit SDL_FREE?

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
jammernich
Beiträge: 38
Registriert: Di 5. Nov 2024, 22:36
OS, Lazarus, FPC: Win11, Lazarus 4.5, fpc 3.2.3

SDL3_package : Welche Resourcen muss ich manuell freigeben mit SDL_FREE?

Beitrag von jammernich »

Hallo,

Sdl3 gibt eigentlich immer einen Pointer zurück. Manche Resourcen benutzen folgendes Schema:

Code: Alles auswählen

function SDL_CreateXXX(Parameter..)  : PSDL_XXXTyp;
procedure SDL_DestroyXXX(p : PSDL_XXX);
z.B. Surfaces, Texturen..

Dann ist ja soweit klar, ich muss die Resource mit SDL_Destroy(..) manuell aus dem Speicher freigeben wenn sie nicht mehr benötigt und das zwingend beim Verlassen des Programms.

Wie ist das bei anderen Sachen die SDL ausspuckt ? Wann muss ich

Code: Alles auswählen

SDL_Free(p : pointer);
verwenden?

Was ist der saubere Pascal-Weg? Und wie kann ich das überprüfen, dass mein Programm nichts "übersieht" und im Speicher lässt.

Viele Grüße

jammernich
Beiträge: 38
Registriert: Di 5. Nov 2024, 22:36
OS, Lazarus, FPC: Win11, Lazarus 4.5, fpc 3.2.3

Re: SDL3_package : Welche Resourcen muss ich manuell freigeben mit SDL_FREE?

Beitrag von jammernich »

Code: Alles auswählen

program project1;

{$mode objfpc}{$H+}{$J-}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils, Classes, SDL3,
  { you can add units after this }
  sglib_logging, sglib_baseclass, sglib_application, sglib_resource,
  sglib_resourcemanager, sglib_handle64; //, sglib_window;

type
  EGame = Class(EApplication);

  { TGame }

  TGame = Class(TApplication)
  public
    procedure Quit; override;
    procedure Init; override;
    procedure Run; override;
    constructor Create;
    destructor Destroy; override;
  end;

// hier fehlt etwas...  
  
Var
  game : TGame = nil;

begin
  game := TGame.Create;
  try
    try
      game.Init;
      game.Run;
    except
      on E: Exception do
      begin
        SGLib_Log('ERROR','An Exception was raised: ' + E.ClassName + ': ' + E.Message ,SDL_GetError,True);
      end;
    end;
  finally
    FreeAndNil(game); //calls Cleanup + SDL_Quit to Destroy SDL SubSystems
  end;
end.
So etwa sieht mein Hauptprogramm aus (project1.lpr). Der Code dient der Veranschaulichung.

Mathias
Beiträge: 7185
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: SDL3_package : Welche Resourcen muss ich manuell freigeben mit SDL_FREE?

Beitrag von Mathias »

Dies sind die Gegenstücke von SDL_free, aller Speicher der mit folgenden 3 Funktionen reserviert wurde, muss damit frei gegeben werden. Vielfach ist die bei Funktionen der Fall, welche einen PChar retour geben. Da muss man in der Doku von SDL3 schauen.
Aber Achtung, es ist NICHT kompatibel zu GetMem und FreeMem.

Code: Alles auswählen

function SDL_malloc(size: Tsize_t): pointer; cdecl; external libSDL3;
function SDL_calloc(nmemb: Tsize_t; size: Tsize_t): pointer; cdecl; external libSDL3;
function SDL_realloc(mem: pointer; size: Tsize_t): pointer; cdecl; external libSDL3;
procedure SDL_free(mem: pointer); cdecl; external libSDL3;
Dann ist ja soweit klar, ich muss die Resource mit SDL_Destroy(..) manuell aus dem Speicher freigeben wenn sie nicht mehr benötigt und das zwingend beim Verlassen des Programms.
Dies sind alles sogenannte struct Pointer, der Fachbegriff Opaque Pointers. Die meisten C-Bindungen bauen darauf auf, welch C keine echte Objektorientierung kennt. Der Pointer der du da bekommst zeigt intern auf eine private struct/record. Sobald du ZB. SDL_CreateWindow aufrufst, wie der Speicher für diese struct intern mit SDL_Malloc reserviert, ähnlich eines Contructors. und mit SDL_DestroWindows, wird dieser interne Speicher wieder aufgeräumt, wie in einem Destructor, die struct slebst wird dann intern mit SDL_free frei gegeben.
Ich hoffe du verstehst was ich meine.

Das beste Beispiel von einer Opaque Pointers: Programmierung ist die glib2.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

jammernich
Beiträge: 38
Registriert: Di 5. Nov 2024, 22:36
OS, Lazarus, FPC: Win11, Lazarus 4.5, fpc 3.2.3

Re: SDL3_package : Welche Resourcen muss ich manuell freigeben mit SDL_FREE?

Beitrag von jammernich »

Hallo Mathias, Danke für die ausführliche Antwort. :)
Mathias hat geschrieben: So 8. Feb 2026, 08:32 Dies sind die Gegenstücke von SDL_free, aller Speicher der mit folgenden 3 Funktionen reserviert wurde, muss damit frei gegeben werden. Vielfach ist die bei Funktionen der Fall, welche einen PChar retour geben. Da muss man in der Doku von SDL3 schauen.
Aber Achtung, es ist NICHT kompatibel zu GetMem und FreeMem.

Code: Alles auswählen

function SDL_malloc(size: Tsize_t): pointer; cdecl; external libSDL3;
function SDL_calloc(nmemb: Tsize_t; size: Tsize_t): pointer; cdecl; external libSDL3;
function SDL_realloc(mem: pointer; size: Tsize_t): pointer; cdecl; external libSDL3;
procedure SDL_free(mem: pointer); cdecl; external libSDL3;
Also die von SDL zurückgegebenen PChars und auch SDL-Pointer wie IDs-Strukturen sind Kandidaten. Hab das auch in den Beispielen in deinem Github Repository zum SDL3-Package gesehen.
->
Woran erkenne ich das denn genau, wenn ich im SDLWiki eine SDL3-Funktion anschaue, dass ich SDL_Free() auf einen Pointer anwenden sollte um den Speicher wieder freizugeben? Das ist eine Frage zu C/C++. Kannst du mir da bitte noch einen Hinweis geben.
Mathias hat geschrieben: So 8. Feb 2026, 08:32 Dies sind alles sogenannte struct Pointer, der Fachbegriff Opaque Pointers. Die meisten C-Bindungen bauen darauf auf, welch C keine echte Objektorientierung kennt. Der Pointer der du da bekommst zeigt intern auf eine private struct/record. Sobald du ZB. SDL_CreateWindow aufrufst, wie der Speicher für diese struct intern mit SDL_Malloc reserviert, ähnlich eines Contructors. und mit SDL_DestroWindows, wird dieser interne Speicher wieder aufgeräumt, wie in einem Destructor, die struct slebst wird dann intern mit SDL_free frei gegeben.
Ich hoffe du verstehst was ich meine.

Das beste Beispiel von einer Opaque Pointers: Programmierung ist die glib2.
Ja, im SDL-Wiki steht dann immer präzise der Hinweis SDL_Destroy().. anzuwenden. Soweit verstanden :)

Mathias
Beiträge: 7185
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: SDL3_package : Welche Resourcen muss ich manuell freigeben mit SDL_FREE?

Beitrag von Mathias »

Das beste Beispiel von einer Opaque Pointers: Programmierung ist die glib2.
Ich habe mal sowas selbst nachgebaut. Bei diesem Beispiel müsste man nur noch cdecl hinten anhängen und man könnte damit einen C kompatiblen export machen.

https://github.com/sechshelme/Lazarus-O ... _tools.pas
Woran erkenne ich das denn genau, wenn ich im SDLWiki eine SDL3-Funktion anschaue, dass ich SDL_Free() auf einen Pointer anwenden sollte um den Speicher wieder freizugeben? Das ist eine Frage zu C/C++. Kannst du mir da bitte noch einen Hinweis geben.
Wen nichts in der Api Doku steht, funktioniet manchmal auch try und run.
Mit folgendem Kommando kann man Specher Leeks erkennen. Nur werden leider auch solche angezeigt, welche in der lib intern sind.

Code: Alles auswählen

valgrind --leak-check=full ./project1
Oder vielfach wen man ein free zuviel hat kommt sowieso eine Warnung und dann ist es zu viel.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten