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);
精彩评论