forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Memory leak

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
AllSystemGo



Joined: 02 Jun 2007
Posts: 26

PostPosted: Mon Aug 27, 2007 11:51 pm    Post subject: Memory leak Reply with quote

Hi everyone,

I curently have a problem with memory leak I think. I created a new class that draws all the icons on screen, and for some reason as soon as I create a second icon the PSP goes into a loop the shutdown. If I only create one it paints on the screen perfectly. I'll post what I think is the relevant code.

Main.cpp

Code:


SDL_Surface *ecran = SDL_SetVideoMode(480, 272, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);


Button butCalendar(125, 80, 67, 80, "data/gfx/calendar.png", "Calendar", 15);
Button butSettings(218, 80, 67, 80, "data/gfx/tools.png", "Settings", 15);

    while(isrunning)
    {      
      butCalendar.Render(ecran);
      butSettings.Render(ecran);
      SDL_Flip(ecran);
    }




Button.cpp
Code:

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>

#include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspdisplay.h>
#include <psprtc.h>

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string>

#include "Button.h"

using namespace std;

Button::Button(SDL_Rect bounds, const char *imagePath, const char *text, int fontSize) : Bounds(bounds), ImagePath(imagePath), Text(text), FontSize(fontSize)
{
}

Button::Button(Sint16 x, Sint16 y, Uint16 width, Uint16 height, const char *imagePath, const char *text, int fontSize) : ImagePath(imagePath), Text(text), FontSize(fontSize)
{
   SDL_FreeSurface(TextSurface);
   SDL_FreeSurface(ImageSurface);
   
   if(FontObject == NULL)
      FontObject = CreateFont();
   if(TextSurface == NULL)
      TextSurface = CreateText();
   if(ImageSurface == NULL)
      ImageSurface = CreateImage();

   SDL_Rect temp = {x, y, width, height};
   Bounds = temp;
}

Button::~Button()
{
   if(FontObject != NULL)
      TTF_CloseFont(FontObject);
   if(TextSurface != NULL)
      SDL_FreeSurface(TextSurface);
   if(ImageSurface != NULL)
      SDL_FreeSurface(ImageSurface);
}

void Button::Render(SDL_Surface* screen)
{
   Render(screen, Bounds);
}

void Button::Render(SDL_Surface* screen, SDL_Rect bounds)
{
   SDL_Rect imageRect;
   imageRect.y = bounds.y;
   imageRect.x = bounds.x + (bounds.w / 2 - ImageSurface->w / 2);
   
   SDL_Rect textRect;
   int textWidth;
   int textHeight;
   TTF_SizeText(FontObject, Text, &textWidth, &textHeight);
   textRect.y = (bounds.y + bounds.h) - textHeight;
   textRect.x = bounds.x + (bounds.w / 2 - textWidth / 2);   
   
   SDL_BlitSurface(ImageSurface, NULL, screen, &imageRect);
   SDL_BlitSurface(TextSurface, NULL, screen, &textRect);
}

bool Button::Contains(SDL_Rect point)
{
   return point.x >= Bounds.x && point.x <= (Bounds.x + Bounds.w) &&
         point.y >= Bounds.y && point.y <= (Bounds.y + Bounds.h);
}

TTF_Font* Button::CreateFont()
{
   return TTF_OpenFont("data/font/Rippen.ttf", FontSize);
}
SDL_Surface* Button::CreateText()
{
   SDL_Color white = {255, 255, 255};

   return TTF_RenderText_Blended(FontObject, Text, white);
}
SDL_Surface* Button::CreateImage()
{
   return SDL_DisplayFormatAlpha(IMG_Load(ImagePath));
}


Thank you for your help. If you need more code let me know!!!

Cheers!
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Tue Aug 28, 2007 4:12 am    Post subject: Reply with quote

If you check some of the older threads, you'll find someone else had almost the same problem. You simple can't sit in a loop calling SDL_Flip() or the PSP goes out to lunch. You need something to delay things - a call to sceKernelDelayThread(), a check of the rtc time, a wait on the vbl...
Back to top
View user's profile Send private message AIM Address
AllSystemGo



Joined: 02 Jun 2007
Posts: 26

PostPosted: Tue Aug 28, 2007 5:41 am    Post subject: Reply with quote

I do understand what you are saying J.F. but the thing is if I remove the Button butSettings(xxxxx); and the butSettings.Render(ecran);

Everything loads perfectly. That is my concern, why when I declare a second button the PSP stays black for 15 seconds then shutdown...

Thxs
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Tue Aug 28, 2007 6:51 am    Post subject: Reply with quote

Okay. I don't see a TTF_Init() in there, and you might try checking if the CreateFont() (and other similar calls in Button) fail. Your code just assumes that all calls are working without error. Maybe the second Button created has one of them failing.
Back to top
View user's profile Send private message AIM Address
danzel



Joined: 04 Nov 2005
Posts: 182

PostPosted: Tue Aug 28, 2007 11:41 am    Post subject: Reply with quote

Code:

Button::Button(Sint16 x, Sint16 y, Uint16 width, Uint16 height, const char *imagePath, const char *text, int fontSize) : ImagePath(imagePath), Text(text), FontSize(fontSize)
{
   SDL_FreeSurface(TextSurface);
   SDL_FreeSurface(ImageSurface);
   
   if(FontObject == NULL)
      FontObject = CreateFont();
   if(TextSurface == NULL)
      TextSurface = CreateText();
   if(ImageSurface == NULL)
      ImageSurface = CreateImage();


Why do you free these surfaces in the constructor, and then optionally recreate them?

They could be uninitialised variables (Hard to tell if they are from the code pasted), and SDL_FreeSurface()'ing them would be bad, possibly crashable.
Back to top
View user's profile Send private message
AllSystemGo



Joined: 02 Jun 2007
Posts: 26

PostPosted: Tue Aug 28, 2007 1:19 pm    Post subject: Reply with quote

Thank you for the replies. I will check into the TTF_Init missing, and for Danzel the FreeSurface wasn't there before and it still crashed, I'll remove that and try with the TTF_Init

Thank you again.
Back to top
View user's profile Send private message
AllSystemGo



Joined: 02 Jun 2007
Posts: 26

PostPosted: Wed Aug 29, 2007 1:58 am    Post subject: Reply with quote

Still the same problem. I'll repost my main.cpp and the class

main.cpp

Code:

/*
iPDA
June 18 2007
*/

#include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspdisplay.h>
#include <psppower.h>
#include <psprtc.h>
#include <png.h>

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string>
#include <list>
#include <iostream>
#include <fstream>

#include "alarm.h"
#include "alarmmanager.h"
#include "button.h"

using namespace std;

PSP_MODULE_INFO("iPDA", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

static bool isrunning = true;
static int curWindow = 1;

// Exit callback
int exit_callback(int arg1, int arg2, void *common) {
   isrunning = false;
   sceKernelExitGame();
   return 0;
}

// Callback thread
int CallbackThread(SceSize args, void *argp) {
   int cbid;
   
   cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
   sceKernelRegisterExitCallback(cbid);
   
   sceKernelSleepThreadCB();
    
   return 0;
}

// Sets up the callback thread and returns its thread id
int SetupCallbacks(void) {
   int thid = 0;
    
   thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
   if(thid >= 0)
   {
      sceKernelStartThread(thid, 0, 0);
   }
    
   return thid;
}

int main() {
    //Initialize the controler
    SceCtrlData pad;
    sceCtrlSetSamplingCycle(0);
    sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
    u64 CurTick;
    u64 CmpTick;
    char timeText[8];
   
    sceRtcGetCurrentTick(&CmpTick);
   
    //Initialize the PSP Time
    pspTime time;
   
    //Initialize the SDL Library (audio and video)
    if(SDL_Init(SDL_INIT_VIDEO) < 0)
      cout << stderr << "Couldn't initialize SDL: " << SDL_GetError() << endl;

    //Initialize the SDL True Type Font Library
    if(TTF_Init() < 0)
      cout << stderr << "Couldn't initialize TTF: " << SDL_GetError() << endl;

    //Initialize the font color.
    SDL_Color white = {255, 255, 255};
    SDL_Color black = {0, 0, 0};
   
    //Initializing the images and text.
      Button butCalendar(125, 80, 67, 80, "data/gfx/calendar.png", "Calendar", 15);
      Button butSettings(218, 80, 67, 80, "data/gfx/tools.png", "Settings", 15);
      

    //Initialize the mouse.
    SDL_Rect mouse = {239, 134};

    //Initialize the Joystick.
    SDL_Rect posJoy;
    posJoy.x = pad.Lx-128;
    posJoy.y = pad.Ly-128;
               
    SDL_Surface *ecran = SDL_SetVideoMode(480, 272, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
   
    SDL_Surface *textTime = NULL;

    //Initialize the callbacks
    pspDebugScreenInit();
    SetupCallbacks();
      
    //Start the loop
    while(isrunning)
    {      
      sceCtrlReadBufferPositive(&pad, 1); //Read the joystick
      sceRtcGetCurrentClockLocalTime(&time); //Get the current time
      
      //Move the mouse on screen
      if((pad.Lx < 35) && (mouse.x > 0))
      {
         mouse.x = mouse.x-3;
      }
      else if((pad.Lx > 200) && (mouse.x < 480))
      {
         mouse.x = mouse.x+3;
      }
      
      if((pad.Ly < 35) && (mouse.y > 0))
      {
         mouse.y = mouse.y-3;
      }
      else if((pad.Ly > 200) && (mouse.y < 480))
      {
         mouse.y = mouse.y+3;
      }
      
      // Don't let the mouse go off screen
      if(mouse.x >= 470)(mouse.x = 470);
      if(mouse.y >= 265)(mouse.y = 265);
      
      sceRtcGetCurrentTick(&CurTick);
      
       //Verify that a second passed before blitting the new clock. This was done to correct the problem were the clock disapear for blitting to many times.
      if (sceRtcCompareTick(&CurTick, &CmpTick) >= 0)
      {
         SDL_FreeSurface(textTime);
         snprintf(timeText, 8, "%02i : %02i", time.hour, time.minutes);
         
         textTime = TTF_RenderText_Shaded(timeFont, timeText, white, black);

         sceRtcGetTick(&time, &CmpTick);
         sceRtcTickAddMinutes(&CmpTick, &CmpTick, 1);
         SDL_BlitSurface(textTime, NULL, ecran, &txttime_position);
      }
   
      if (curWindow == 1)
      {
         if (pad.Buttons & PSP_CTRL_CROSS)
         {
            if ((mouse.x > calculator_position.x) && (mouse.x < (calculator_position.x + 64)) &&
                (mouse.y > calculator_position.y) && (mouse.y < (calculator_position.y + 64)))
            {
               curWindow = 2;
            }
         }
         
         butCalendar.Render(ecran);
         butSettings.Render(ecran);
      }
      
      SDL_BlitSurface(mousePointer, NULL, ecran, &mouse);      
      SDL_Flip(ecran);
    }
   
    //Free the memory.
   
    SDL_FreeSurface(mousePointer);

    TTF_Quit();
    SDL_Quit();
   
    sceKernelSleepThread();

    return 0;
}



button.cpp

Code:

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>

#include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspdisplay.h>
#include <psprtc.h>

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string>
#include <iostream>
#include <fstream>

#include "button.h"

using namespace std;

Button::Button(SDL_Rect bounds, const char *imagePath, const char *text, int fontSize) : Bounds(bounds), ImagePath(imagePath), Text(text), FontSize(fontSize)
{
}

Button::Button(Sint16 x, Sint16 y, Uint16 width, Uint16 height, const char *imagePath, const char *text, int fontSize) : ImagePath(imagePath), Text(text), FontSize(fontSize)
{
   
   FontObject = CreateFont();
   TextSurface = CreateText();
   ImageSurface = CreateImage();
   
   SDL_Rect temp = {x, y, width, height};
   Bounds = temp;
}

Button::~Button()
{
   if(FontObject != NULL)
      TTF_CloseFont(FontObject);
   if(TextSurface != NULL)
      SDL_FreeSurface(TextSurface);
   if(ImageSurface != NULL)
      SDL_FreeSurface(ImageSurface);
}

void Button::Render(SDL_Surface* screen)
{
   Render(screen, Bounds);
}

void Button::Render(SDL_Surface* screen, SDL_Rect bounds)
{
   SDL_Rect imageRect;
   imageRect.y = bounds.y;
   imageRect.x = bounds.x + (bounds.w / 2 - ImageSurface->w / 2);
   
   SDL_Rect textRect;
   int textWidth;
   int textHeight;
   TTF_SizeText(FontObject, Text, &textWidth, &textHeight);
   textRect.y = (bounds.y + bounds.h) - textHeight;
   textRect.x = bounds.x + (bounds.w / 2 - textWidth / 2);   
   
   SDL_BlitSurface(ImageSurface, NULL, screen, &imageRect);
   SDL_BlitSurface(TextSurface, NULL, screen, &textRect);
}

bool Button::Contains(SDL_Rect point)
{
   return point.x >= Bounds.x && point.x <= (Bounds.x + Bounds.w) &&
         point.y >= Bounds.y && point.y <= (Bounds.y + Bounds.h);
}

TTF_Font* Button::CreateFont()
{
   return TTF_OpenFont("data/font/Rippen.ttf", FontSize);
}
SDL_Surface* Button::CreateText()
{
   SDL_Color white = {255, 255, 255};
   
   if(FontObject == NULL)
      CreateFont();
   
   return TTF_RenderText_Blended(FontObject, Text, white);
}
SDL_Surface* Button::CreateImage()
{
   return SDL_DisplayFormatAlpha(IMG_Load(ImagePath));
}


I still get the same problem. If I remove the Button butSettings everything loads up perfectly but as soon as I add the second button then the PSP stay black for about 10 seconds then shutdown.

Thanks for your help.

Cheers.
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Wed Aug 29, 2007 6:04 am    Post subject: Reply with quote

You're still not checking if your surfaces are created. Try adding a check in the Render function.

Code:
   if (ImageSurface != NULL)
      SDL_BlitSurface(ImageSurface, NULL, screen, &imageRect);
   if (TextSurface != NULL)
      SDL_BlitSurface(TextSurface, NULL, screen, &textRect);


If that works, then you know that one of the surfaces fails to be created the second time a button is created. Your program has very little error checking - it's something you need to worry about, at least until you get the bugs worked out.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group