2012-11-16 14 views
11

Co dzieje się ze statyczną zmienną, gdy jest zwracana jako odniesienie i przekazywana jako wskaźnik bezpośrednio do innej funkcji? Oczywiście zmienna utrzymuje się po powrocie funkcji, ale coś w tej całej koncepcji mnie martwi. W którym momencie następuje zwolnienie pamięci w sekwencji danych zajmowanej przez zmienną statyczną? Czy środowisko wykonawcze w magiczny sposób zauważa, kiedy już go nie potrzebuję, na przykład coś w rodzaju zbierania śmieci?Zwracanie statycznych zmiennych lokalnych jako odniesień

Aby dać przykład:

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); 
    } 
} 

Co się dzieje rect po SDL_BlitSurface() zwraca? Nie widzę, kiedy zostałaby uwolniona. Czy to nie byłby jakiś wyciek pamięci?

Odpowiedz

10

W którym punkcie znajduje się pamięć w sekwencji danych, zajmowanej przez zmienną statyczną , zwalniana? Czy środowisko wykonawcze w magiczny sposób zauważa, że ​​nie potrzebuję go dłużej, jak na przykład odbiór śmieci?

Zostanie zwolniony przy wyjściu programu, a nie wcześniej. Zapewnia to również wywoływanie destruktorów.

+0

Więc nadal będzie on pochłaniał ogromne ilości pamięci, biorąc pod uwagę, że działa w nieskończonej pętli, prawda? Czy też zastępuje się za każdym razem, gdy wywoływana jest funkcja XSDL_RectConstr()? Ponadto, SDL_rect jest strukturą, a nie klasą, a zatem nie ma destruktora, ale myślę, że to nie ma znaczenia. – CaffeineAddict

+1

To nadpisuje się, to jest problem. Każda struktura (i każda klasa) ma destruktor, jeśli go nie napiszesz, generowany jest jeden. – john

+1

Nie "nadpisuje" niczego. To ten sam obiekt. Jedyną magią jest to, że nie jest skonstruowana, dopóki nie po raz pierwszy nie wejdziesz w tę funkcję; poza zwykłymi regułami scopingu, nie ma w tym nic innego, jak "statyczny" zdefiniowany w zakresie przestrzeni nazw. To jak statyczny "członek" funkcji. –

4

rect nie zostaną zwolnione po powrocie z SDL_BlitSurface, ale nie będzie to również wyciek pamięci: jest w pamięci statycznej, więc nie ma nic do "wycieku". Obiekt pozostanie w pamięci tak długo, jak długo twój program działa.

Największym minusem tego zjawiska jest sytuacja, w której uruchamiana jest wielowątkowość: zmienna statyczna może być jednocześnie modyfikowana z wielu wątków, co należy raczej unikać.

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

Mogę po prostu naprawić problem wielowątkowości za pomocą blokady mutex wokół funkcji, prawda? – CaffeineAddict

+0

@cyberpunk_ Tak, to prawda. Muteks musi być wokół wywołania funkcji i obejmować kod, w którym używasz wartości ze zmiennej statycznej wraz z samym wywołaniem. – dasblinkenlight

4

Nie ma przeciek pamięci, ale to naprawdę, naprawdę zły pomysł. Załóżmy, że napisałeś jakiś kod jak ten

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

Ponieważ masz tylko jeden statyczny prostokąt, SDL_someFunction nie dostanie różnych prostokątów, że wygląda na to, że będzie się dostać. Zamiast tego otrzymasz dwa razy ten sam prostokąt.

+0

Więc przypuszczam, że jeśli użyję tego, aby upewnić się, że zawsze otrzymuję te same dane, to jest ok, prawda? –