Возвращение статических локальных переменных в качестве ссылок

Что происходит со статической переменной при возврате в качестве ссылки и передается как указатель непосредственно на другую функцию? Очевидно, переменная сохраняется после возвращения функции, но что-то об этой целой концепции меня просто беспокоит. В какой момент происходит освобождение памяти на секвенции данных, занятой статической переменной? Является ли время выполнения волшебным, когда мне это больше не нужно, например, какая-то сборка мусора?

Чтобы привести пример:

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

Что произойдет с rect после возврата SDL_BlitSurface()? Я не вижу, когда это будет освобождено. Разве это не будет какой-то утечкой памяти?

Ответ 1

В какой момент это память на секвенции данных, занятая статическая переменная, освобожденная? Является ли время выполнения волшебным, когда я нет дольше это нужно, как какая-то сборка мусора?

Он будет освобожден при выходе программы, не раньше. Кроме того, он гарантировал, что деструкторы будут вызваны.

Ответ 2

rect не будет освобожден после возврата из SDL_BlitSurface, но это также не будет утечкой памяти: он находится в статическом хранилище, поэтому нет "утечки". Объект будет оставаться в памяти до тех пор, пока ваша программа будет запущена.

Самый большой недостаток этого происходит, когда вы запускаете многопоточность: ваша статическая переменная подвержена риску изменения из нескольких потоков одновременно, чего вы бы предпочли избежать.

Деструкторы для инициализированных объектов статической продолжительности хранения (объявлены в области блока или в области пространства имен) вызываются в результате возврата из main и в результате вызова exit.

Ответ 3

Там нет утечки памяти, но это действительно, очень плохая идея. Предположим, вы написали код вроде этого

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

Поскольку у вас есть только один статический прямоугольник, SDL_someFunction не собирается получать разные прямоугольники, которые, по-видимому, собираются получить. Вместо этого вы получите тот же прямоугольник дважды.