Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Another newbie question (100% cpu usage and memory leak)

This thread is locked; no one can reply to it. rss feed Print
Another newbie question (100% cpu usage and memory leak)
Justin Slowik
Member #7,235
May 2006

hey i'm working on getting the basic components down for a game I am working on in my spare time, and I have just started doing keyboard initiated movement. However,if I open the task manager while the program is running, it shows CPU usage at 100%, and if I move my character up and down, my pagefile usage and overall memory usage slowly climb. Here's the main parts of my movement code:

Main (skipped over basic initialization code):

  while(!(key[KEY_ESC])){    //begin main game loop
    if (keypressed())
    {    
      animatePC(character_data,landFile,playerPos);
      clear_keybuf();
    }
  }

animatePC:

1void animatePC(const DATAFILE *character_data,const DATAFILE *landFile, position &playerPos)
2{
3 
4 BITMAP *buffer = create_bitmap(SCREEN_W, SCREEN_H);
5 int newY = playerPos.posY;
6 if(key[KEY_DOWN]){ //if down key is hit, walk down to next tile
7 int count = 0;
8 for(; newY < playerPos.posY + 32 ; newY++)
9 {
10 if(count == 2)
11 count = 0;
12 else
13 count++;
14 buffer = draw_map(landFile);
15 draw_sprite(buffer,(BITMAP *)character_data[count].dat,0,newY);
16 DrawDoublebuffer(buffer);
17 destroy_bitmap(buffer);
18 }
19 count = 0;
20 
21 }
22 else if(key[KEY_UP]){ //else if up key is hit, walk up to next tile
23 int frameCount = 11;
24 for(; newY > playerPos.posY - 32 ; newY--)
25 {
26 if(frameCount == 12)
27 frameCount = 10;
28 else
29 frameCount++;
30 
31 buffer = draw_map(landFile);
32 draw_sprite(buffer,(BITMAP *)character_data[frameCount].dat,0,newY);
33 DrawDoublebuffer(buffer);
34 destroy_bitmap(buffer);
35 }
36 frameCount = 11;
37 }
38 playerPos.posY = newY;
39}

Doublebuffer Code:

void DrawDoublebuffer(BITMAP *buffer) {
    acquire_screen();
    blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
    release_screen();
}

and finally Drawmap

1BITMAP *draw_map(const DATAFILE *landFile)
2{
3 BITMAP *buff = create_bitmap(SCREEN_W, SCREEN_H);
4 clear_bitmap(buff);
5 
6 int mapXtotal = 20 * 32;
7 int mapYtotal = 18 * 32;
8 for (int x = 0; x < mapXtotal; x = x+32){
9 for (int y = 0; y <= mapYtotal; y = y+32){
10 draw_sprite(buff,(BITMAP *)landFile[0].dat,x,y);
11 }
12 }
13 int size = text_length(font, versionNumber.c_str()); //display version number
14 textout_right_ex(buff, font, versionNumber.c_str(), SCREEN_W-10, SCREEN_H-10, makecol(255,255,255), -1);
15 return buff;
16}

any help for fixing either of these problems would be greatly appreciated. as far as I can tell I'm destroying all bitmaps after they're used, so I dont know why the memory usage continues to climb every time I move in a direction. As for the 100% cpu, I'm assuming its cause I'm constantly checking for a keypress. if thats the reason for it, is there an easy way to fix this? any help would be greatly appreciated. thanks

Matthew Leverton
Supreme Loser
January 1999
avatar

Regarding 100% CPU usage, you'll have to throw a rest(1) in there somewhere. Keep in mind that it will probably rest for 10ms. Or you can rest(0) which "plays nice," but still uses 100% CPU.

gnolam
Member #2,030
March 2002
avatar

And as for the memory leak, you never destroy "buff" in draw_map().

That said, don't recreate your buffers every time. It's horribly inefficient. Create them once at the start of the program and destroy them once at the end.

Also, look into separating your logic and your drawing...

[EDIT]
If I were you I'd dump the acquire and release as well when I was at it, as you're only doing one operation to the screen. Chances are that, one day, you'll be tempted to put something that doesn't belong there in between them... and then your program will die a gruesome death.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Justin Slowik
Member #7,235
May 2006

thanks for the rest() idea. that fixed the cpu time a bunch! now as for the leak I seem to be having, i realized its not my main memory thats leaking anymore, it does increase while moving but when I stop it goes back down again. however, my pagefile usage does climb slowly but surely. And I'm afraid after an extended period of time I'll overflow. Any other ideas on that? the pagefile seems to climb 1-5 MB every time I move 1 tile space.

[edit]
thanks gnolam for the advice. I'll be separating stuff out at some point, right now I'm just trying to get the basics down as they come to me. I'll be separating into classes and such probably later in the weekend. And i'll look into the tips you gave me now, see if any of them affect the mem usage.

ReyBrujo
Moderator
January 2001
avatar

I believe your code has a great memory leak. See function animatePC. You create a buffer. But you only destroy it a couple of times inside for cycles. Your function should be like this instead:

1void animatePC(const DATAFILE *character_data,const DATAFILE *landFile, position &playerPos)
2{
3 
4 BITMAP *buffer = create_bitmap(SCREEN_W, SCREEN_H);
5 int newY = playerPos.posY;
6 if(key[KEY_DOWN]){ //if down key is hit, walk down to next tile
7 int count = 0;
8 for(; newY < playerPos.posY + 32 ; newY++)
9 {
10 if(count == 2)
11 count = 0;
12 else
13 count++;
14 buffer = draw_map(landFile);
15 draw_sprite(buffer,(BITMAP *)character_data[count].dat,0,newY);
16 DrawDoublebuffer(buffer);
17 }
18 count = 0;
19 
20 }
21 else if(key[KEY_UP]){ //else if up key is hit, walk up to next tile
22 int frameCount = 11;
23 for(; newY > playerPos.posY - 32 ; newY--)
24 {
25 if(frameCount == 12)
26 frameCount = 10;
27 else
28 frameCount++;
29 
30 buffer = draw_map(landFile);
31 draw_sprite(buffer,(BITMAP *)character_data[frameCount].dat,0,newY);
32 DrawDoublebuffer(buffer);
33 }
34 frameCount = 11;
35 }
36 playerPos.posY = newY;
37 destroy_bitmap(buffer);
38}

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Justin Slowik
Member #7,235
May 2006

ReyBrujo, I tried your idea, and it just made my pagefile leakage climb at least 2 or 3 times faster. shrug This is gonna drive me insane hah. lets see if i clean up my code how i do.

ReyBrujo
Moderator
January 2001
avatar

Hehehe, the problem is that draw_map is creating bitmaps that are never being destroyed too. This code should work. Don't create a bitmap inside animatePC:

1void animatePC(const DATAFILE *character_data,const DATAFILE *landFile, position &playerPos)
2{
3 
4 BITMAP *buffer;
5 int newY = playerPos.posY;
6 if(key[KEY_DOWN]){ //if down key is hit, walk down to next tile
7 int count = 0;
8 for(; newY < playerPos.posY + 32 ; newY++)
9 {
10 if(count == 2)
11 count = 0;
12 else
13 count++;
14 buffer = draw_map(landFile);
15 draw_sprite(buffer,(BITMAP *)character_data[count].dat,0,newY);
16 DrawDoublebuffer(buffer);
17 destroy_bitmap(buffer);
18 }
19 count = 0;
20 
21 }
22 else if(key[KEY_UP]){ //else if up key is hit, walk up to next tile
23 int frameCount = 11;
24 for(; newY > playerPos.posY - 32 ; newY--)
25 {
26 if(frameCount == 12)
27 frameCount = 10;
28 else
29 frameCount++;
30 
31 buffer = draw_map(landFile);
32 draw_sprite(buffer,(BITMAP *)character_data[frameCount].dat,0,newY);
33 DrawDoublebuffer(buffer);
34 destroy_bitmap(buffer);
35 }
36 frameCount = 11;
37 }
38 playerPos.posY = newY;
39}

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Justin Slowik
Member #7,235
May 2006

Thanks Rey! that fixed it now. I appreciate the help now i cna move on w/ my life hah.

A J
Member #3,025
December 2002
avatar

create_bitmap() is a signifacnt cost, only do it if you have to.
also ALWAYS check its return code, so if it actaully worked.

___________________________
The more you talk, the more AJ is right. - ML

Go to: