2012-11-16 80 views
11

將靜態變量作爲引用返回並作爲指針直接傳遞給另一個函數時會發生什麼?顯然,變量在函數返回後依然存在,但關於這個概念的一些事情讓我感到困擾。在哪一點上,數據後綴上的內存由靜態變量佔用,釋放?運行時是否會奇蹟般地注意到我不再需要它,比如某種垃圾收集?將靜態局部變量作爲引用返回

舉個例子:

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

SDL_BlitSurface()返回後會發生什麼rect?我無法看到它何時會被釋放。那麼這會不會是某種內存泄漏?

回答

10

在哪一點上的數據後綴的內存,由 靜態變量佔用,釋放?當我沒有 需要它時,運行時神奇地注意到,像某種垃圾收集?

它將在程序退出時釋放,不會更早。此外,它保證會調用析構函數。

+0

因此,它仍然會佔用大量的內存,因爲它在無限循環中運行,對吧?還是每次調用XSDL_RectConstr()時都會覆蓋自身?此外,SDL_rect是一個結構,而不是一個類,因此沒有析構函數,但我想這是無關緊要的。 – CaffeineAddict

+1

它覆蓋自身,這就是問題所在。每個結構體(和每個類)都有一個析構函數,如果你不寫一個,就會生成一個默認的結構體。 – john

+1

它不會「覆蓋」任何東西。這是同一個對象。這裏唯一的奇妙之處在於它只有在你第一次輸入該函數時纔會被構造出來;除了通常的範圍規則之外,與命名空間範圍中定義的'static'相比,這沒什麼不同。它就像一個靜態的「成員」的功能。 –

4

rect將不會從SDL_BlitSurface返回時被釋放,但它也不會是內存泄漏:它在靜態存儲中,所以沒有什麼可以「泄漏」。只要程序正在運行,該對象將保留在內存中。

當你開始多線程時,最大的缺點是你的靜態變量存在被多個線程同時修改的風險,這是你應該避免的。

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

我可以通過在函數週圍使用互斥鎖來解決多線程問題,對嗎? – CaffeineAddict

+0

@cyberpunk_是的,這是正確的。互斥體需要圍繞函數的調用,幷包含代碼,其中使用靜態變量的值以及調用本身。 – dasblinkenlight

4

有沒有內存泄漏,但它是一個非常非常糟糕的主意。假設你寫了一些這樣的代碼

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

因爲你只有一個靜態的矩形,SDL_someFunction是不會得到它看起來像它會得到不同的矩形。相反,你會得到相同的矩形兩次。

+0

所以我想如果我用這個來確保我總是得到相同的數據,沒關係,對吧? –

相關問題