2012-11-16 6 views
11

Was passiert mit einer statischen Variablen, wenn sie als Referenz zurückgegeben und als Zeiger direkt an eine andere Funktion übergeben wird? Offensichtlich bleibt die Variable nach der Rückkehr der Funktion bestehen, aber etwas an diesem ganzen Konzept stört mich. An welchem ​​Punkt wird der Speicher auf der Datensequenz, belegt durch die statische Variable, freigegeben? Spürt die Laufzeit auf magische Weise, wenn ich sie nicht mehr brauche, wie eine Art Müllsammlung?Statische lokale Variablen als Referenzen zurückgeben

ein Beispiel geben:

SDL_Rect* XSDL_RectConstr(int x, int y, int w, int h) 
{ 
    static SDL_Rect rect; 
    rect.x = x; 
    rect.y = y; 
    rect.w = w; 
    rect.h = h; 

    return ▭ 
} 

void mainLoop() 
{ 
    while(isRunning) 
    { 
     pollEvents(); 
     SDL_BlitSurface(someSurface, XSDL_RectConstr(0, 0, 100, 100), screen, NULL); 
     SDL_Flip(screen); 
    } 
} 

Was nach SDL_BlitSurface() kehrt zu rect passiert? Ich kann nicht sehen, wann es befreit werden würde. Wäre das nicht eine Art Speicherleck?

Antwort

10

An welchem ​​Punkt wird der Speicher auf der Datensequenz, belegt durch die statische Variable, freigegeben? Merkst du die Laufzeit magisch wenn ich keine länger brauche, wie eine Art Garbage Collection?

Es würde am Programm Exit freigegeben werden, nicht früher. Außerdem wird garantiert, dass Destruktoren aufgerufen werden.

+0

Also wird es immer noch riesige Mengen an Speicher verschwenden, da es in einer Endlosschleife läuft, oder? Oder überschreibt es sich jedes Mal, wenn XSDL_RectConstr() aufgerufen wird? Außerdem ist SDL_rect eine Struktur, keine Klasse und hat daher keinen Destruktor, aber ich denke, das ist irrelevant. – CaffeineAddict

+1

Es überschreibt sich selbst, das ist das Problem. Jede Struktur (und jede Klasse) hat einen Destruktor, wenn Sie keinen schreiben, wird ein Standard-Destruktor generiert. – john

+1

Es "überschreibt" nichts. Es ist das gleiche Objekt. Die einzige Magie hier ist, dass es nicht konstruiert wird, bis Sie diese Funktion das erste Mal betreten; Abgesehen von den üblichen Scoping-Regeln gibt es an dieser Stelle nichts anderes als ein im Namespace-Bereich definiertes statisches Attribut. Es ist wie ein statisches "Mitglied" der Funktion. –

4

rect wird nicht bei der Rückkehr von SDL_BlitSurface freigegeben werden, aber es wäre auch kein Speicherverlust: Es ist im statischen Speicher, also gibt es nichts zu "lecken". Das Objekt bleibt so lange im Speicher, wie das Programm läuft.

Der größte Nachteil dabei ist, wenn Sie Multithreading starten: Ihre statische Variable läuft Gefahr, gleichzeitig von mehreren Threads geändert zu werden, was Sie lieber vermeiden würden.

Destructors for initialized objects of static storage duration (declared at block scope or at namespace scope) are called as a result of returning from main and as a result of calling exit.

+0

Ich könnte das Multithreading-Problem einfach beheben, indem ich einen Mutex-Lock um die Funktion verwende, richtig? – CaffeineAddict

+0

@cyberpunk_ Ja, das ist richtig. Der Mutex muss sich um den Aufruf der Funktion befinden und den Code umfassen, in dem Sie den Wert aus der statischen Variablen zusammen mit dem Aufruf selbst verwenden. – dasblinkenlight

4

Es gibt keinen Speicherverlust, aber es ist ein wirklich, wirklich schlechte Idee. Angenommen, Sie einige Codes wie dies

SDL_someFunction(
    XSDL_RectConstr(0, 0, 100, 100), 
    XSDL_RectConstr(20, 20, 30, 30) 
); 

schrieben Weil du nur ein statisches Rechteck hat, SDL_someFunction nicht die verschiedenen Rechtecken in Gang zu bringen, die es sieht aus wie es bekommen los ist. Stattdessen erhalten Sie zweimal dasselbe Rechteck.

+0

Also ich nehme an, wenn ich das benutze, um sicherzustellen, dass ich immer die gleichen Daten bekomme, ist das in Ordnung, oder? –