2012-11-16 37 views
11

Điều gì sẽ xảy ra với biến tĩnh khi được trả về làm tham chiếu và được truyền trực tiếp dưới dạng con trỏ tới hàm khác? Rõ ràng, biến vẫn tồn tại sau khi hàm trả về, nhưng một cái gì đó về toàn bộ khái niệm này chỉ làm phiền tôi. Tại thời điểm đó là bộ nhớ trên trình tự dữ liệu, bị chiếm bởi biến tĩnh, được giải phóng? Liệu thời gian chạy có được thông báo một cách kỳ diệu khi tôi không còn cần đến nó nữa, giống như một số loại thu gom rác thải không?Trả lại biến cục bộ tĩnh dưới dạng tham chiếu

Để đưa ra một ví dụ:

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

Điều gì xảy ra sau khi rect SDL_BlitSurface() trả về? Tôi không thể thấy khi nào nó được giải phóng. Nó sẽ không phải là một loại rò rỉ bộ nhớ sau đó?

Trả lời

10

Tại thời điểm nào là bộ nhớ trên trình tự dữ liệu, bị chiếm bởi biến số tĩnh , được giải phóng? Thời gian chạy có thực sự đáng chú ý khi tôi không còn cần nữa, như một số loại thu gom rác thải không?

Nó sẽ được giải phóng khi thoát chương trình, không sớm hơn. Ngoài ra, nó được đảm bảo rằng destructors sẽ được gọi.

+0

Vì vậy, nó sẽ vẫn hog lên một lượng lớn bộ nhớ, cho rằng nó đang chạy trong một vòng lặp vô hạn, phải không? Hay nó ghi đè lên chính nó mỗi khi XSDL_RectConstr() được gọi? Ngoài ra, SDL_rect là một cấu trúc, không phải là một lớp, và do đó không có một destructor, nhưng tôi đoán đó là không thích hợp. – CaffeineAddict

+1

Nó ghi đè chính nó, đó là vấn đề. Mỗi cấu trúc (và mọi lớp) có một destructor, nếu bạn không viết một cái mặc định được tạo ra. – john

+1

Nó không "ghi đè lên" bất cứ điều gì. Đó là cùng một đối tượng. Phép thuật duy nhất ở đây là nó không được xây dựng cho đến lần đầu tiên bạn nhập hàm đó; ngoài các quy tắc phạm vi thông thường, không có gì khác biệt về điều này hơn là một 'tĩnh' được định nghĩa trong phạm vi không gian tên. Nó giống như một "thành viên" tĩnh của hàm. –

4

rect sẽ không được giải phóng khi trở về từ SDL_BlitSurface, nhưng nó sẽ không bị rò rỉ bộ nhớ: trong bộ nhớ tĩnh, vì vậy không có gì để "rò rỉ". Đối tượng sẽ ở trong bộ nhớ miễn là chương trình của bạn đang chạy.

Nhược điểm lớn nhất cho điều này xảy ra khi bạn bắt đầu đa luồng: biến tĩnh của bạn chạy một nguy cơ bị sửa đổi từ nhiều luồng đồng thời, đó là điều mà bạn muốn tránh.

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

Tôi có thể khắc phục sự cố đa luồng bằng cách sử dụng khóa mutex xung quanh chức năng, đúng không? – CaffeineAddict

+0

@cyberpunk_ Vâng, điều này là chính xác. Các mutex cần phải được xung quanh cuộc gọi của hàm và bao gồm mã nơi bạn sử dụng giá trị từ biến tĩnh cùng với lời gọi chính nó. – dasblinkenlight

4

Không có bộ nhớ bị rò rỉ, nhưng đó là một thực sự, thực sự xấu ý tưởng. Giả sử bạn đã viết một số mã như thế này

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

Bởi vì bạn chỉ có một hình chữ nhật tĩnh, SDL_someFunction sẽ không để có được những hình chữ nhật khác nhau mà có vẻ như nó đang diễn ra để có được. Thay vào đó, bạn sẽ nhận được cùng một hình chữ nhật hai lần.

+0

Vì vậy, tôi cho rằng nếu tôi sử dụng điều này để đảm bảo tôi luôn nhận được cùng một dữ liệu, điều đó ổn, đúng không? –

Các vấn đề liên quan