Texturen müssen mit der SDL_DestroyTexture
Funktion zerstört werden, und Sie tun nicht das, was auf dem Speicherverlust führt.
übrigens manuell die Zerstörung Funktion auf einem Rohzeiger aufrufen, wenn Sie nicht mehr benötigen fehleranfällig ist (man leicht einen Fall vergessen kann, wo es gehen muss) und unnötig, mit der wunderbaren Welt der Ressourcen Acquisition Ist Initialisierung (RAII).
Sicherstellen, dass die erworbenen Ressourcen ordnungsgemäß entsorgt werden, ist in C++ eigentlich eine ziemlich häufige Anforderung, und eine, für die es gut geeignet ist. Sie können die Objektlebensdauer zum Verwalten von Ressourcen für Sie mithilfe von RAII abrufen, bei der Sie Destruktor/Deallokationscode im Destruktor der Klasse platzieren, sodass dieser automatisch ausgeführt wird, wenn das Objekt, das die Ressource verwaltet, den Gültigkeitsbereich verlässt. Dies macht die Ausnahmesicherheit ebenfalls einfach, da der Destruktorcode auch im Falle einer Ausnahme ausgeführt wird.
In Ihrem Fall haben Sie einen Klassenspeicher einen Zeiger auf das erstellte SDL-Objekt, und rufen Sie dann die entsprechende SDL Ende der Lebensdauer Funktion für die Vielzahl der Objekte im Destruktor verwaltet, also a Textur-Management-Klasse könnte wie folgt aussehen:
class Texture{
SDL_Texture* texture_;
public:
// or simply pass the arguments for texture creation in and create it internally
Texture(SDL_Texture* texture) : texture_{texture}{}
~Texture(){
if (texture_ != nullptr){
SDL_DestroyTexture(texture_);
}
}
// ... functions to access texture
};
Beachten Sie aber, dass Sie im wesentlichen einen Zeiger auf eine Ressource mit atypischen End-of-Lebensdauer Anforderungen Verpackung und dass diese Anforderungen sind im wesentlichen eine freie Funktion aufzurufen, die nimmt den Zeiger als Argument, vorausgesetzt, es ist kein Nullzeiger.
Sie brauchen nicht eine bestimmte Klasse zu machen dass-- unique_ptr
war entworfen für diesen Job zu tun und wird es vortrefflich tun, wenn Sie es eine benutzerdefinierte deleter geben. Einen benutzerdefinierten Deleter zu geben ist eine einfache Aufgabe, auch unique_ptr
.
Wenn Sie eine Funktion haben, die einen Zeigertyp T*
als einziges Argument nimmt und beendet die Lebensdauer des spitzen Gegenstand und einen zugehörigen Speicher, es ist so einfach wie diese:
#include <memory>
void shoutFooDestruction(Foo* foo); // my special lifetime ending function
int main(){
std::unique_ptr<Foo, decltype(&shoutFooDestruction)> ptr{
new Foo(),
shoutFooDestruction};
ptr.reset(new Foo());
}
Dies ruft shoutFooDestruction
zweimal: einmal für den ursprünglichen Zeiger, der dem eindeutigen Zeiger zu Beginn seiner Lebensdauer gegeben wurde, und aufgerufen, wenn reset
war, und einmal für den Foo, der beim Zurücksetzen geliefert wurde, wenn die Lebensdauer des unique_pointer am Ende von main
endet.
See it live on Coliru
Das Äquivalent für eine SDL_Texture wäre:
std::unique_ptr<SDL_Texture, &SDL_DestroyTexture> message{
nullptr,
SDL_DestroyTexture};
und für eine SDL_Surface:
std::unique_ptr<SDL_Surface, &SDL_FreeSurface> surfaceMessage{
nullptr,
SDL_FreeSurface};
würden Sie dann reset
auf die einzigartigen Zeiger aufrufen, wenn Sie wollte eine neue Textur oder Oberfläche von SDL, und sie würden jede alte Textur oder Oberfläche entsorgen e für dich. Alle verbleibenden Inhalte der unique_ptr
s am Ende der Funktion würden mit den gleichen Funktionen behandelt werden, wenn die unique_ptr
s außerhalb des Geltungsbereichs ging.
1. Wie in 3 Konstrukteurs gesehen und 4
2. reset
Aufruf auf einem einzigartigen Zeiger mit nullptr
für ihr Wert will not call the provided deleter und das gleiche gilt für unique_ptr
's destructor, so dass Sie nicht Sie müssen sich darum sorgen, den Löschanruf zu vermeiden, wenn Sie nichts zu löschen haben.
Muss 'Message' den Speicher freigeben? – NathanOliver
@NathanOliver-Texturen brauchen tatsächlich ihren Speicher frei, obwohl die Funktion * technisch * ['SDL_DestroyTexture'] benannt ist (https://wiki.libsdl.org/SDL_DestroyTexture). OP wäre vielleicht am besten mit 'std :: unique_ptr' aber – jaggedSpire
@jaggedSpire Cool. Ich habe nie SDL verwendet, also war es nur eine Vermutung, da es ein Zeiger war und die Oberfläche gereinigt wurde. – NathanOliver