Изучение C ++ и SDL - вызывает ли следующее утечку памяти? - PullRequest
1 голос
/ 05 января 2011

Я немного изучаю C ++ и не совсем уверен, что хорошо разбираюсь в управлении памятью.Я знаю только Java и немного PHP и Python, так что это немного ново для меня.Я тоже работаю с SDL - мне показалось, что это интересный способ ускорить процесс обучения.В любом случае, я пытаюсь написать функцию очистки, которая освобождает все поверхности, которые были переданы в стек (я просто использую стек STL).Итак, у меня есть следующий код (сокращенно):

#include <stack>

//stack of SDL_Surfaces  
stack<SDL_Surface*> surfaces;

void clean() {      
    SDL_Surface *temp = NULL;

    //loops through the stack depending on its size
    while (surfaces.size() != 0) {
        temp = surfaces.top();
        SDL_FreeSurface(temp);
        surfaces.pop();

    } //while
    if (surfaces.size() == 0) {
        cout << "cleanup worked correctly" << endl;     
    } //if
}

//loading an image (this is in the main function)
background = load_image( "background.bmp" );
surfaces.push(background);

//cleaning time
clean();

Я не уверен насчет метода очистки.Я подумал, что это будет лучший способ реализовать функцию SDL_FreeSurface, а не указывать каждую поверхность вручную.Поэтому, если бы я нарисовал на экране десять изображений (скажем, десять космических кораблей), а затем взорвал их, мне нужно было бы их правильно удалить.Я бы создал стек для этих 10 кораблей, а затем, после их уничтожения, я мог бы уничтожить их всех, если это имеет смысл.Я беспокоюсь, что я слишком усложнил вещи и ввел совершенно новый способ вызвать утечку памяти.Я новичок в C ++, так что не стесняйтесь издеваться над моей тщетной попыткой управления памятью.

Ответы [ 5 ]

2 голосов
/ 05 января 2011

Ваш собственный код не имеет утечки памяти.Предполагая, что load_image() также безопасен, весь код очищен от утечек памяти.

Помните, что если вы не используете оператор new, утечки памяти не происходит.

1 голос
/ 05 января 2011

Похоже, что нет утечек памяти. Тем не менее, вы хотите убедиться, что вы не держите поверхности слишком долго, иначе может возникнуть утечка (то же самое может случиться в Java). Если предположить, что clean вызывается достаточно часто, у вас все будет в порядке.

Это переносит проблему очистки отдельных поверхностей (путем вызова SDL_FreeSurface в соответствующее время) на очистку стека поверхностей (путем вызова clean в соответствующее время). Если у вас уже есть код (или идея) для управления стеком, я бы пошел дальше и поработал с ним. Если нет, я бы попытался найти способ индивидуального управления временем жизни на поверхности, поскольку этот подход более гибкий и не вводит новую концепцию.

1 голос
/ 05 января 2011

Это немного сбивает с толку то, что вы делаете, но если SDL_FreeSurface () освобождает объект (???), то я не вижу утечки памяти.

Что вы пытаетесь сделать?Что делает SDL_FreeSurface ()?Что делает load_image () и как он распределяет память, если он вообще это делает?

0 голосов
/ 24 июля 2014

лучший способ найти утечки памяти - это использовать valgrind. Насколько я знаю, это работает только на Linux, но оно того стоит, чтобы исследовать и использовать.

0 голосов
/ 07 января 2011

Прочитайте о RAII - C ++ очень хорош в этом. Как только вы поймете, что происходит (в основном это выделение ресурсов в конструкторе и освобождение в деструкторе - это означает, что ваши объекты очищаются), - вы можете создать красивые оболочки для функций SDL. Вот как бы вы сделали поверхность:

CBitmapSurface::CBitmapSurface(const std::string &filename) 
{
    m_pSurface = SDL_LoadBMP(filename.c_str());
}

CBitmapSurface::~CBitmapSurface()
{
    SDL_FreeSurface(m_pSurface); 
}

где m_pSurface - переменная-член типа SDL_Surface *.

В идеальном мире вы бы хотели, чтобы этот класс не копировался, обрабатывайте конструктор перемещения, если используете c ++ 0x, проверяйте коды ошибок и генерируйте исключения. Но это должно помочь вам начать.

...