TTF memory vacuum
Moderator: Coders of Rage
-
- Chaos Rift Regular
- Posts: 198
- Joined: Thu Mar 26, 2009 8:42 pm
- Current Project: My Engine
- Programming Language of Choice: C++
TTF memory vacuum
So my game has hit a stand still because when you run the program for like 5 seconds the memory goes to 100,000k of usage. it fluctuates alot but it's not a memory leak. A memory leak would only go up in a linear fashion right? Anyways I've heard that some people have this problem when rendering changing text every frame because of the TTF library. Does anyone know how to fix it?
My first game: http://donsvoice.com/randomdever/Duck%2 ... 01.0.0.zip
My second game: http://donsvoice.com/randomdever/Space%20Invaders.zip
My third game: http://donsvoice.com/randomdever/BreakOut!.zip
My second game: http://donsvoice.com/randomdever/Space%20Invaders.zip
My third game: http://donsvoice.com/randomdever/BreakOut!.zip
- Bakkon
- Chaos Rift Junior
- Posts: 384
- Joined: Wed May 20, 2009 2:38 pm
- Programming Language of Choice: C++
- Location: Indiana
Re: TTF memory vacuum
I had a problem like this once because every frame I was opening the font I was using and then not closing it. Can't say much else without seeing some code.
-
- Chaos Rift Regular
- Posts: 198
- Joined: Thu Mar 26, 2009 8:42 pm
- Current Project: My Engine
- Programming Language of Choice: C++
Re: TTF memory vacuum
Bakkon wrote:I had a problem like this once because every frame I was opening the font I was using and then not closing it. Can't say much else without seeing some code.
Code: Select all
void StateManager::DrawState()
{
if( state == MAIN_MENU )
{
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0, 0, 0 ) );
//TTF_SetFontStyle( comicsans, TTF_STYLE_UNDERLINE );
title = TTF_RenderText_Solid( comicsans, "_________", orange );
ApplySurface( 320 - ( title->clip_rect.w / 2 ), 50, title, screen );
//TTF_SetFontStyle( comicsans, TTF_STYLE_NORMAL );
title = TTF_RenderText_Solid( comicsans, "DUCK HUNT", cyan );
ApplySurface( 320 - ( title->clip_rect.w / 2 ), 50, title, screen );
screen = TTF_RenderCenteredText_Solid( arial, "Start!", white, startDuckHunt.button, screen );
ApplySurface( 272, 224, startDuckHunt.GetImage(), screen, startDuckHunt.nextClip );
screen = TTF_RenderCenteredText_Solid( arial, "High Scores", white, highScores.button, screen );
ApplySurface( 272, 258, highScores.GetImage(), screen, highScores.nextClip );
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[0].c_str(), white );
ApplySurface( screen->clip_rect.w / 2 - highestScore->clip_rect.w / 2, 430, highestScore, screen );
SDL_Flip( screen );
}
if( state == DUCK_HUNT )
{
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0, 0, 0 ) );
ApplySurface( 0, 410, gUI, screen );
ApplySurface( 30, 415, gUIShot, screen );
switch( shotsRemaining )
{
case 1: ApplySurface( 15, 440, gUIBullet, screen ); break;
case 2: ApplySurface( 15, 440, gUIBullet, screen ); ApplySurface( 42, 440, gUIBullet, screen ); break;
case 3: ApplySurface( 15, 440, gUIBullet, screen ); ApplySurface( 42, 440, gUIBullet, screen ); ApplySurface( 70, 440, gUIBullet, screen ); break;
}
gUIPoints = TTF_RenderText_Solid( arialLarge, scoreBuf.c_str(), white );
if( atoi( scoreBuf.c_str() ) != score )
{
scoreBuf = intToString( score );
}
ApplySurface( 120, 415, gUIHit, screen );
ApplySurface( 555, 415, gUIScore, screen );
ApplySurface( 543, 435, gUIPoints, screen );
SDL_Flip( screen );
}
if( state == HIGH_SCORES )
{
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0, 0, 0 ) );
if( score > (unsigned int)atoi( scores[1].c_str() ) )
{
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 128, 128, 255 ) );
name.Show( 250, 380, screen, false );
}
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[0].c_str(), white );
ApplySurface( 250, 40, highestScore, screen );
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[1].c_str(), white );
ApplySurface( 250, 100, highestScore, screen );
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[2].c_str(), white );
ApplySurface( 250, 160, highestScore, screen );
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[3].c_str(), white );
ApplySurface( 250, 220, highestScore, screen );
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[4].c_str(), white );
ApplySurface( 250, 280, highestScore, screen );
screen = TTF_RenderCenteredText_Solid( arial, "Back", white, back.button, screen );
ApplySurface(20, 444, back.GetImage(), screen, back.nextClip );
SDL_Flip( screen );
}
}
void StateManager::SoundState()
{
if( state == MAIN_MENU )
{
}
}
void StateManager::EventState()
{
if( state == MAIN_MENU )
{
time = SDL_GetTicks();
previousState = MAIN_MENU;
while( SDL_PollEvent( &event ) )
{
if( startDuckHunt.Check( event ) )
{
state = DUCK_HUNT;
SDL_WM_SetCaption( "Duck Hunt", NULL );
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0, 0, 0 ) );
}
if( highScores.Check( event ) )
{
back.Reset();
state = HIGH_SCORES;
SDL_WM_SetCaption( "High Scores", NULL );
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0, 0, 0 ) );
}
if( event.type == SDL_QUIT )
{
quit = true;
}
}
stateManager.DrawState();
while( framesPerSecond / 1000 > SDL_GetTicks() - time )
{
}
}
if( state == DUCK_HUNT )
{
time = SDL_GetTicks();
previousState = DUCK_HUNT;
while( SDL_PollEvent( &event ) )
{
if( event.type == SDL_KEYDOWN )
{
if( event.key.keysym.sym == SDLK_TAB )
{
back.Reset();
state = HIGH_SCORES;
}
}
if( event.type == SDL_QUIT )
{
quit = true;
}
}
stateManager.DrawState();
}
if( state == HIGH_SCORES )
{
time = SDL_GetTicks();
while( SDL_PollEvent( &event ) )
{
if( score > (unsigned int)atoi( scores[1].c_str() ) && previousHuntState == GAME_OVER )
{
if( event.type == SDL_KEYDOWN )
{
name.HandleInput( event, arcadeclassic, white );
}
if( name.GetString().length() == 3 && score > (unsigned int)atoi( scores[1].c_str() ) )
{
newHighScore( name.GetString().c_str(), score );
}
}
if( back.Check( event ) )
{
state = previousState;
highScores.Reset();
startDuckHunt.Reset();
}
if( event.type == SDL_QUIT )
{
quit = true;
}
}
stateManager.DrawState();
}
}
My first game: http://donsvoice.com/randomdever/Duck%2 ... 01.0.0.zip
My second game: http://donsvoice.com/randomdever/Space%20Invaders.zip
My third game: http://donsvoice.com/randomdever/BreakOut!.zip
My second game: http://donsvoice.com/randomdever/Space%20Invaders.zip
My third game: http://donsvoice.com/randomdever/BreakOut!.zip
Re: TTF memory vacuum
You render surfaces but you don't free the memory.
http://jcatki.no-ip.org:8080/SDL_ttf/SD ... html#SEC43
Quote of the most important part:
http://jcatki.no-ip.org:8080/SDL_ttf/SD ... html#SEC43
Quote of the most important part:
The caller (you!) is responsible for freeing any returned surface.
-
- Chaos Rift Regular
- Posts: 198
- Joined: Thu Mar 26, 2009 8:42 pm
- Current Project: My Engine
- Programming Language of Choice: C++
Re: TTF memory vacuum
So I'm supposed to free the surfaces before the program quits?dani93 wrote:You render surfaces but you don't free the memory.
http://jcatki.no-ip.org:8080/SDL_ttf/SD ... html#SEC43
Quote of the most important part:The caller (you!) is responsible for freeing any returned surface.
My first game: http://donsvoice.com/randomdever/Duck%2 ... 01.0.0.zip
My second game: http://donsvoice.com/randomdever/Space%20Invaders.zip
My third game: http://donsvoice.com/randomdever/BreakOut!.zip
My second game: http://donsvoice.com/randomdever/Space%20Invaders.zip
My third game: http://donsvoice.com/randomdever/BreakOut!.zip
- Bakkon
- Chaos Rift Junior
- Posts: 384
- Joined: Wed May 20, 2009 2:38 pm
- Programming Language of Choice: C++
- Location: Indiana
Re: TTF memory vacuum
When you call TTF_RenderText_Solid, you are creating memory for an SDL_Surface, so you need to free that memory once you're done.
Re: TTF memory vacuum
Simple: Free them when you don't need them anymore.RandomDever wrote:So I'm supposed to free the surfaces before the program quits?dani93 wrote:You render surfaces but you don't free the memory.
http://jcatki.no-ip.org:8080/SDL_ttf/SD ... html#SEC43
Quote of the most important part:The caller (you!) is responsible for freeing any returned surface.
I assume this function gets called in a loop. So you reassign new surfaces everytime the function is called. The previously assigned surfaces are lost, but they still exist in memory (-> memory leak). So you need to free them when the function quits or even better right after blitting it the last time. Because you use the same pointer for several surfaces you will need to free each of them, not only the last!
- hurstshifter
- ES Beta Backer
- Posts: 713
- Joined: Mon Jun 08, 2009 8:33 pm
- Favorite Gaming Platforms: SNES
- Programming Language of Choice: C/++
- Location: Boston, MA
- Contact:
Re: TTF memory vacuum
This thread just lead me to the source of a leak that I had in one of my program I had as well. The ttf's were the last place I thought to look. Sweet!
"Time is an illusion. Lunchtime, doubly so."
http://www.thenerdnight.com
http://www.thenerdnight.com
-
- Chaos Rift Regular
- Posts: 198
- Joined: Thu Mar 26, 2009 8:42 pm
- Current Project: My Engine
- Programming Language of Choice: C++
Re: TTF memory vacuum
dani93 wrote: Because you use the same pointer for several surfaces you will need to free each of them, not only the last!
How?
My first game: http://donsvoice.com/randomdever/Duck%2 ... 01.0.0.zip
My second game: http://donsvoice.com/randomdever/Space%20Invaders.zip
My third game: http://donsvoice.com/randomdever/BreakOut!.zip
My second game: http://donsvoice.com/randomdever/Space%20Invaders.zip
My third game: http://donsvoice.com/randomdever/BreakOut!.zip
-
- Chaos Rift Junior
- Posts: 345
- Joined: Tue Jan 12, 2010 7:23 pm
- Favorite Gaming Platforms: PC - Windows 7
- Programming Language of Choice: c++;haxe
- Contact:
Re: TTF memory vacuum
By deleteing (delete SurfacePtr; ) each unused surface before reassigning the pointer.RandomDever wrote:dani93 wrote: Because you use the same pointer for several surfaces you will need to free each of them, not only the last!
How?
I think you should brush up on pointers before you use them any further.
http://www.cplusplus.com/doc/tutorial/pointers/
A basic understanding of pointers is a MUST if you plan to use them to avoid the very issues your having :P
- Bakkon
- Chaos Rift Junior
- Posts: 384
- Joined: Wed May 20, 2009 2:38 pm
- Programming Language of Choice: C++
- Location: Indiana
Re: TTF memory vacuum
Code: Select all
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[0].c_str(), white );
ApplySurface( 250, 40, highestScore, screen );
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[1].c_str(), white );
ApplySurface( 250, 100, highestScore, screen );
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[2].c_str(), white );
ApplySurface( 250, 160, highestScore, screen );
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[3].c_str(), white );
ApplySurface( 250, 220, highestScore, screen );
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[4].c_str(), white );
ApplySurface( 250, 280, highestScore, screen );
Code: Select all
for(int i = 0; i < 5; i++)
{
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[i].c_str(), white );
ApplySurface( 250, i * 60 + 40, highestScore, screen );
SDL_FreeSurface(highestScore);
}
- short
- ES Beta Backer
- Posts: 548
- Joined: Thu Apr 30, 2009 2:22 am
- Current Project: c++, c
- Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
- Programming Language of Choice: c, c++
- Location: Oregon, US
Re: TTF memory vacuum
However if his compiler does not unwind this when it optimizes the code he would be slowing his code down. Just sayin.Bakkon wrote:This part of your code can be fixed and condensed by doing this...Code: Select all
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[0].c_str(), white ); ApplySurface( 250, 40, highestScore, screen ); highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[1].c_str(), white ); ApplySurface( 250, 100, highestScore, screen ); highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[2].c_str(), white ); ApplySurface( 250, 160, highestScore, screen ); highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[3].c_str(), white ); ApplySurface( 250, 220, highestScore, screen ); highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[4].c_str(), white ); ApplySurface( 250, 280, highestScore, screen );
Code: Select all
for(int i = 0; i < 5; i++) { highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[i].c_str(), white ); ApplySurface( 250, i * 60 + 40, highestScore, screen ); SDL_FreeSurface(highestScore); }
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
link: https://github.com/bjadamson
Re: TTF memory vacuum
Disregard this, bakkon's is much bettershort wrote:However if his compiler does not unwind this when it optimizes the code he would be slowing his code down. Just sayin.
- dandymcgee
- ES Beta Backer
- Posts: 4709
- Joined: Tue Apr 29, 2008 3:24 pm
- Current Project: https://github.com/dbechrd/RicoTech
- Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
- Programming Language of Choice: C
- Location: San Francisco
- Contact:
Re: TTF memory vacuum
I'm pretty sure any decent compiler is going to be much more successful at optimizing a for loop than magically realizing 50 lines of code are different by 1 number.short wrote:However if his compiler does not unwind this when it optimizes the code he would be slowing his code down. Just sayin.Bakkon wrote:This part of your code can be fixed and condensed by doing this...Code: Select all
highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[0].c_str(), white ); ApplySurface( 250, 40, highestScore, screen ); highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[1].c_str(), white ); ApplySurface( 250, 100, highestScore, screen ); highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[2].c_str(), white ); ApplySurface( 250, 160, highestScore, screen ); highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[3].c_str(), white ); ApplySurface( 250, 220, highestScore, screen ); highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[4].c_str(), white ); ApplySurface( 250, 280, highestScore, screen );
Code: Select all
for(int i = 0; i < 5; i++) { highestScore = TTF_RenderText_Solid( arcadeclassic, scoresList[i].c_str(), white ); ApplySurface( 250, i * 60 + 40, highestScore, screen ); SDL_FreeSurface(highestScore); }
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches!