开发者

Memory leak on painting

I'm trying to create a simple game, but I can't find a certain memory leak. Every second or so, the program seems to use 3mb more memory.

The problem is with this draw method. If I don't call this method, everything works fine. I'm trying to paint a sprite on several parts of the screen:

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

If I remove the method call of draw, there are no problems, so the problem is in that method:

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开发者_StackOverflow中文版(this->hSpriteDC, this->hImage);
    BitBlt(hBackBufferDC, x, y, 22, 22, this->hSpriteDC, 0, 0, SRCPAINT);

    SelectObject(this->hSpriteDC, oldObj);
}

Any idea what is causing the memory leak here? I think it's related to this part, but I can post other parts of the code if needed.

Thanks


Are you using managed c++ or not ? You are allocating new Position (24*27) times. This lead to a 648 leaks each time you call Map::draw.

Use an automatic object.

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

Or delete the Position object after using it ! Note that dynamic allocation is very slow.

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


new Position() requires a corresponding delete.

if(mapState[i][j] == 'm') {
  Position P(j, i);
  blueWall->draw(hBackBufferDC, &P);
}


As others have pointed out, you shouldn't dynamically allocate Position.

A more idiomatic solution: Remove "new"...

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

and pass by const reference...

void StaticSprite::draw(HDC hBackBufferDC, const Position& pos) 
{
    int x = (int)pos.x * 22;
    int y = (int)pos.y * 22;
    ...


To be more efficient you should declare the automatic variable before looping, and then just update its members:

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

This solution doesn't require you to change your method' signature.


Instead of

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

Why not try:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜