Jump to content
  • Advertisement
Sign in to follow this  
Toadhead

memory leak in my tetris clone?

This topic is 4823 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I get an error, something like "Cannot read instruction referenced to memory on 0x0060fd pointed to 0x0d4395. Cant read memory" Or something like that (mine is in Dutch so I hope I translated it abit right ;) ) I guess its some kind of memory leak but I cannot find it :( I tried to fix it for over 3 hours now and its realy making me crazy >:( I get the error when I open my game, click on "Start game", click on "Stop" so I return to the title screen, and click on quit. I get it when I quit my game. Also when I click on Start Game and I wait a long time the computer ets very slow. I guess the problem is in game.cpp since if I open the options screen or the credits screen etc. I dont get any problems. This is the main.cpp file:
//Including header files
#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>

#include "SDL.h"
#include "SDL_ttf.h"
#include "SDL_mixer.h"
#include "SDL_image.h"

//Including the main.h header files which includes the BaseFrame initialization
#include "framebase.h"
#include "loading.h"
#include "titlescreen.h"
#include "credits.h"
#include "options.h"
#include "game.h"

//Using the standard namespace
using namespace std;


//Main starts here
int main(int argc, char** argv) 
{
FrameBase *Fpointer = NULL; //This pointer can point to all classes based on FrameBase
LoadFrame *Lpointer = new LoadFrame;
TitleFrame *Tpointer = new TitleFrame;
CreditsFrame *Cpointer = new CreditsFrame;
OptionsFrame *Opointer = new OptionsFrame;
GameFrame *Gpointer = new GameFrame;

Fpointer =   new LoadFrame;
int fID = 1;

//General Gameloop
bool grun = true;
while(grun == true)
{

fID = Fpointer->Frame();

//Checking which frame is next
if (fID == 0)
{       
grun = false;            
}
else if (fID == 1)
{
Fpointer =  Tpointer;           
}        
else if (fID == 2)
{
Fpointer =  Cpointer;           
}
else if (fID == 3)
{
Fpointer =  Opointer;           
}
else if (fID == 4)
{
Fpointer =  Gpointer;           
}

else
{
 cout << "Error: Couldn't find next frame" << endl; 
 cout << fID << endl;  
 exit(1);    
}





}
//End of general gameloop
    
    
//Deleting pointers
delete Fpointer;
delete Lpointer;
delete Tpointer;
delete Cpointer;
delete Opointer;
delete Gpointer;

//Game ends
 return 0;   
}


And this is the game.cpp file:
// Source file for the Gamescreen

//Including header files
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>

#include "SDL.h"
#include "SDL_ttf.h"
#include "SDL_mixer.h"
#include "SDL_image.h"

// Including the loading.h header file which includes the LoadFrame class initialization
#include "game.h"
#include "framebase.h"
using namespace std;

//Global variables
extern SDL_Surface *screen; //Screen surface
extern SDL_Surface *CursorIMG; //Mouse cursor

// Methods for the GameFrame class defined below

//Constructor
GameFrame::GameFrame() 
{                     
}


// This is whats happens when this frame is used
int GameFrame::Frame() 
{

//Clear screen
SDL_Rect Sdest;
Sdest.x = 0;
Sdest.y = 0;
Sdest.w = 1024;
Sdest.h = 768;
SDL_FillRect(screen, &Sdest, SDL_MapRGB(screen->format,0,0,0));
  
GameScore = 0; //Setting score to 0 

//Loading fonts
G1_font = TTF_OpenFont("Fonts//accid.ttf", 22);
if(!G1_font) {
    printf("TTF_OpenFont: %s\n", TTF_GetError());
    // handle error
    exit(1);
} 
 
  
  
//LOADING IN ALL IMAGES

//Loading image Gamefield.png
    Gamefield = IMG_Load("Images//Gamefield.PNG");   
    
    if (Gamefield == NULL)
        {
              cout << "Couldn't load image \"Gamefield.PNG\"" << endl;              
              exit(1);             
        }
  

//Loading images Stop-1.png and Stop-2.png
    S_IMG = IMG_Load("Images//Stop-1.PNG");
    S2_IMG = IMG_Load("Images//Stop-2.PNG");    
    
    if (S_IMG == NULL)
        {
              cout << "Couldn't load image \"Stop-1.PNG\"" << endl;              
              exit(1);             
        }
        
    if (S2_IMG == NULL)
        {
              cout << "Couldn't load image \"Stop-2.PNG\"" << endl;              
              exit(1);             
        }      

//Loading images Pause-1.png and Pause-2.png
    P_IMG = IMG_Load("Images//Pause-1.PNG");
    P2_IMG = IMG_Load("Images//Pause-2.PNG");    
    
    if (P_IMG == NULL)
        {
              cout << "Couldn't load image \"Pause-1.PNG\"" << endl;              
              exit(1);             
        }
        
    if (P2_IMG == NULL)
        {
              cout << "Couldn't load image \"Pause-2.PNG\"" << endl;              
              exit(1);             
        }      

//END OF LOADING IMAGES









//Sub-gameloop starts here
Loop();



//Freeing up images
SDL_FreeSurface(Gamefield); 
SDL_FreeSurface(S_IMG); 
SDL_FreeSurface(S2_IMG);
SDL_FreeSurface(P_IMG); 
SDL_FreeSurface(P2_IMG);


//Return 1 to return to Title screen  
return 1;

};
//End of frame function















// Sub-Gameloop 
int GameFrame::Loop() 
{
  
  //Loop variables
  Mix_Chunk *click = NULL;                     // Used for the click sound
  click = Mix_LoadWAV("Sounds//click.wav");    //
  if (click == NULL)
  {
  cout << "Couldn't find click.wav" << endl;
  exit(1);
  }

  int cx, cy; //Used to store mouse location
  char scoretext[25];
  SDL_Surface *t_surface = NULL; // Text surface
   
  S_dest.x = 50; // Score button destination
  S_dest.y = 718;
   
  P_dest.x = 800; // Pause button destination
  P_dest.y = 718; 
        
  bool run = true; 
  while(run == true) //Gameloop will loop as long as run == true
  {
            
//Clear screen
SDL_Rect Sdest;
Sdest.x = 0;
Sdest.y = 0;
Sdest.w = 1024;
Sdest.h = 768;
SDL_FillRect(screen, &Sdest, SDL_MapRGB(screen->format,0,0,0));
 
//Event polling    
SDL_Event gevent;
while(SDL_PollEvent(&gevent))
{

}    
//End of event polling


//Draw gamefield
Game_dest.x = 320;
Game_dest.y = 64;
SDL_BlitSurface(Gamefield,NULL,screen,&Game_dest);




//Draw the score on (320,30) using font 1 / color 1
SDL_Color color1={255,0,0}; //Red Color (for score)
SDL_Rect Score_dest;
sprintf(scoretext,"Score: %d",GameScore);
Score_dest.x = 320;
Score_dest.y = 30;
t_surface = TTF_RenderText_Blended(G1_font,scoretext,color1);
SDL_BlitSurface(t_surface,NULL,screen,&Score_dest);
SDL_FreeSurface(t_surface);
//End of drawing score


//Get mouse state saved in cx and cy
SDL_GetMouseState(&cx,&cy); 


//BUTTON DRAWING (stop and pause)
//If mouse cursor is above Stop
if ( (cx >= S_dest.x) && (cx <= (150 + S_dest.x)) && (cy >= S_dest.y) && (cy <= (30 + S_dest.y))) 
{
SDL_BlitSurface(S2_IMG,NULL,screen,&S_dest);
}     
else if ( (cx < S_dest.x) || (cx > (150 + S_dest.x)) || (cy < S_dest.y) || (cy > (30 + S_dest.y)) )
{
SDL_BlitSurface(S_IMG,NULL,screen,&S_dest);
}
else
{
 cout << "Error: Unknown mouse position" << endl;
 exit(1);   
} 


//If mouse cursor is above Pause
if ( (cx >= P_dest.x) && (cx <= (150 + P_dest.x)) && (cy >= P_dest.y) && (cy <= (30 + P_dest.y))) 
{
SDL_BlitSurface(P2_IMG,NULL,screen,&P_dest);
}     
else if ( (cx < P_dest.x) || (cx > (150 + P_dest.x)) || (cy < P_dest.y) || (cy > (30 + P_dest.y)) )
{
SDL_BlitSurface(P_IMG,NULL,screen,&P_dest);
}
else
{
 cout << "Error: Unknown mouse position" << endl;
 exit(1);   
} 
//END OF BUTTON DRAWING

      
    
//Draw mouse cursor
SDL_Rect Mdest;
Mdest.x = cx;
Mdest.y = cy;
SDL_BlitSurface(CursorIMG,NULL,screen,&Mdest);


//End of drawing, screen will be flipped
SDL_Flip(screen);    

//NON DRAWING STUFF GOES BELOW


//Checking for Mouse clicks above the menu items
if (SDL_GetMouseState(NULL,NULL) &SDL_BUTTON(SDL_BUTTON_LEFT) )
{       
     
//Checking if mouse is clicked above Stop
if ((cx >= S_dest.x) && (cx <= (150 + S_dest.x)) && (cy >= S_dest.y) && (cy <= (30 + S_dest.y))) 
{
 //PlaySound click
 Mix_PlayChannel(-1,click,0);     
 SDL_Delay(250);
 run = false;
 Mix_FreeChunk(click);
}

//Checking if mouse is clicked above Pause
if ((cx >= P_dest.x) && (cx <= (150 + P_dest.x)) && (cy >= P_dest.y) && (cy <= (30 + P_dest.y))) 
{
 //PlaySound click
 Mix_PlayChannel(-1,click,0);     
 SDL_Delay(250);
 PauseGame();
}



}
//End of checking for mouse clicks



    
      
  }
//End of sub-gameloop

//Frees everything up
TTF_CloseFont(G1_font);  
//Returning to frame function
return 0;
}
//End of sub-gameloop function







//Start of Pause function
void GameFrame::PauseGame() 
{
     
     
     
}
//End of Pause function





And this is the game.h header file:
#ifndef __GAME
#define __GAME

#include "framebase.h"

class GameFrame : public FrameBase 
{
      
private: 
    
    //Variables
    int GameScore;
    
    SDL_Rect Game_dest;
    SDL_Surface *Gamefield;
    
    SDL_Rect S_dest;     //
    SDL_Surface *S_IMG;  // Stop button to return to titlescreen
    SDL_Surface *S2_IMG; //
    
    SDL_Rect P_dest;    //
    SDL_Surface *P_IMG; // Pause button to pause the game for a few seconds
    SDL_Surface *P2_IMG;//    
    
    TTF_Font *G1_font; //Game font
    
    //The private sub-gameloop function     
    int Loop();           

protected:
                          
public:
      //Public Methods
      int Frame();
      void PauseGame();
      //Constructor
      GameFrame();    
};

#endif



I realy hope someone can help me :( (My tetris clone isnt finished btw) Greatings, Rob

Share this post


Link to post
Share on other sites
Advertisement
You should learn how to use the debugger. Assuming you are using Visual Studio, make sure you are compiling a Debug build (which is the default) and press F5. When the crash occurs, the program will break to the debugger and tell you on which line the exception occurs. In case of memory corruption, this line is often not the actual cause of the problem, but it may give you a clue.

Also, while debugging, you can see the contents of the variables in your program and the call-stack (which function is active, where it was called from ... all the way back to your main program).

Share this post


Link to post
Share on other sites
Yes, but I'm not using VC++.
I'm using dev-cpp and the debugger of dev-cpp sucks :(
I might buy VC++ later when I have enough money but until than I have to do it with Dev-Cpp :(

(I tried to debug it but when I run the program using a debugger it'll crash when I press on Quit which does not happen when I run it normaly). This way it doesnt even reach the memory error at the end. (Btw I dont get any output from the debugger at all)

Share this post


Link to post
Share on other sites
Quote:
Original post by Kippesoep
You should learn how to use the debugger. Assuming you are using Visual Studio, make sure you are compiling a Debug build (which is the default) and press F5. When the crash occurs, the program will break to the debugger and tell you on which line the exception occurs. In case of memory corruption, this line is often not the actual cause of the problem, but it may give you a clue.

Also, while debugging, you can see the contents of the variables in your program and the call-stack (which function is active, where it was called from ... all the way back to your main program).




When would you press the F5 key? when you run the compiled program or when you compile it?

Share this post


Link to post
Share on other sites
I don't see anything too unusual in your code. There's virtually no memory management in there, just SDL stuff. If you post all the code (perhaps as a ZIP file), I could try to compile it under MSVC and see if there's anything its debugger will tell me.

BTW, I can thoroughly recommend MSVC. It's the only MS product I actually enjoy using and the debugger is very good. The upcoming MSVC2k5 Express will be very cheap, too. Just $50. I know some people actually balk at paying for software, but I think that price is more than reasonable.

Share this post


Link to post
Share on other sites
Quote:
Original post by donjonson
When would you press the F5 key? when you run the compiled program or when you compile it?


F5 is the shortcut key for "run with debug". So you'd press it inside the editor. It will then compile/build the program, if necessary, and then run it with the debugger attached.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You could also try the Fluid Studios Memory Manager. It helped me find a lot (all) of my leaks. I don´t remember the address, but I guess you could google for it. (Oh - and it´s free).

I am surprised that you manage to code anything without the use of the debugger though ;)

Cheers!

Share this post


Link to post
Share on other sites
Thanks everyone.
And Kippesoep I tought MSVC was mich more expensive :/
I never realy looked at the prices but I tought it was far above $100 :D

I guess I just buy MSVC than and debug it myself :/

Share this post


Link to post
Share on other sites
Quote:
Original post by Toadhead
I guess I just buy MSVC than and debug it myself :/


Note: I did say "upcoming". That version of MSVC hasn't been released yet (although a free beta can be downloaded). The current versions of MSVC are more expensive (with MSVC2k3 standard costing $150 or so).

Share this post


Link to post
Share on other sites
Yeah but I guess I'm just going to buy 2003 or 2005 when its out I dunno. I dont realy care as long as its not above 500 or so.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!