Утечка памяти при покраске - PullRequest
3 голосов
/ 16 февраля 2011

Я пытаюсь создать простую игру, но не могу найти утечку памяти. Каждую секунду или около того программа, кажется, использует на 3 МБ больше памяти.

Проблема с этим методом рисования. Если я не вызываю этот метод, все работает нормально. Я пытаюсь нарисовать спрайт на нескольких частях экрана:

void Map::draw(HDC hBackBufferDC)   
{  
    for(int i = 0; i < 24; i++)  
    {  
        for(int j = 0; j < 27; j++)  
        {  
            if(mapState[i][j] == 'm')
            {
                blueWall->draw(hBackBufferDC, new Position(j, i));  
            }  
        }
    }
} 

Если я удалю вызов метода draw, проблем не будет, поэтому проблема в этом методе:

void StaticSprite::draw(HDC hBackBufferDC, Position* pos)  
{
    int x = (int)pos->x * 22;
    int y = (int)pos->y * 22;

    HGDIOBJ oldObj = SelectObject(this->hSpriteDC, this->hMask);

    BitBlt(hBackBufferDC, x, y, 22, 22, this->hSpriteDC, 0, 0, SRCAND);

    SelectObject(this->hSpriteDC, this->hImage);
    BitBlt(hBackBufferDC, x, y, 22, 22, this->hSpriteDC, 0, 0, SRCPAINT);

    SelectObject(this->hSpriteDC, oldObj);
}

Есть идеи, что вызывает утечку памяти? Я думаю, что это связано с этой частью, но я могу опубликовать другие части кода, если это необходимо.

Спасибо

Ответы [ 5 ]

4 голосов
/ 16 февраля 2011

Используете ли вы управляемый с ++ или нет? Вы распределяете новую позицию (24 * 27) раз. Это приводит к 648 утечкам каждый раз, когда вы вызываете Map :: draw.

Использовать автоматический объект.

void Map::draw(HDC hBackBufferDC)
    {
    for(int i = 0; i < 24; i++)
       {
       for(int j = 0; j < 27; j++)
         {
           if(mapState[i][j] == 'm') {
              Position tmp(j,i);
              blueWall->draw(hBackBufferDC, &tmp);
           }
         }
       }
    }
    }

Или удалите объект Position после его использования! Обратите внимание, что динамическое распределение очень медленное.

void Map::draw(HDC hBackBufferDC)
    {
    for(int i = 0; i < 24; i++)
       {
       for(int j = 0; j < 27; j++)
         {
           if(mapState[i][j] == 'm') {
              Position *tmp = new Position(j,i);
              blueWall->draw(hBackBufferDC, tmp);
              delete tmp;
           }
         }
       }
    }
    }
3 голосов
/ 16 февраля 2011

новая позиция () требует соответствующего удаления.

if(mapState[i][j] == 'm') {
  Position P(j, i);
  blueWall->draw(hBackBufferDC, &P);
}
2 голосов
/ 16 февраля 2011

Чтобы быть более эффективным, вы должны объявить автоматическую переменную перед циклом, а затем просто обновить ее члены:

void Map::draw(HDC hBackBufferDC)   
{  
    Position pos;
    for(int i = 0; i < 24; i++)  
    {  
        for(int j = 0; j < 27; j++)  
        {  
            if(mapState[i][j] == 'm')
            {
                pos.x = j;
                pos.y = i;
                blueWall->draw(hBackBufferDC, &pos);  
            }  
        }
    }
} 

Это решение не требует, чтобы вы меняли сигнатуру вашего метода.

2 голосов
/ 16 февраля 2011

Как уже отмечали другие, вы не должны динамически распределять Position.

Более идиоматическое решение: удалите "new" ...

blueWall->draw(hBackBufferDC, Position(j, i));

и передайте ссылку на констант...

void StaticSprite::draw(HDC hBackBufferDC, const Position& pos) 
{
    int x = (int)pos.x * 22;
    int y = (int)pos.y * 22;
    ...
1 голос
/ 16 февраля 2011

вместо

blueWall->draw(hBackBufferDC, new Position(j, i));

Почему бы не попробовать:

Position pos(j,i);
blueWall->draw(hBackBufferDC, &pos);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...