7 Replies - 1145 Views - Last Post: 03 August 2014 - 05:19 PM Rate Topic: -----

#1 migcak  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 45
  • Joined: 15-August 12

Problem using SDL_FreeSurface

Posted 18 July 2014 - 02:07 PM

I'm making a simple Tic-Tac-Toe game in SDL but I got an error I've never seen before after I ran the game.
The idea is that the game first displays "Welcome to my game" with a play button under the message. The player can click the button to play the game. After the button is clicked the message and the play button is removed from the screen and the game board appears. They are removed by using two SDL_FreeSurface calls. When I run the game the message and button show up but after I click the button the game freezes and shows me an error message about ten seconds after I click the play button. If I comment out the code where I call SDL_FreeSurface everything works as expected but the message and the button will still be there as I didn't delete them of course. My question is can anyone tell me why am I getting this error message when I call SDL_FreeSurface?
Here's the error I got when I used SDL_FreeSurface:

Windows has triggered a breakpoint in gamepractice.exe.

This may be due to a corruption of the heap, which indicates a bug in gamepractice.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while gamepractice.exe has focus.

The output window may have more diagnostic information.

The following function is where I allow the player to click the play button.

void Button::handle_input()
{
	int x = 0, y = 0;

	if(event.type == SDL_MOUSEBUTTONDOWN)
	{
		if(event.button.button == SDL_BUTTON_LEFT)
		{
			x = event.button.x;
			y = event.button.y;
		}

			if((x > box.x) && (x < box.x + box.w) && (y > box.y) && (y < box.y + box.h))
			{
				//SDL_FreeSurface(message);

				//SDL_FreeSurface(button);

				apply_surface(0, 0, board, screen);
			}
	}
}


Is This A Good Question/Topic? 0
  • +

Replies To: Problem using SDL_FreeSurface

#2 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1000
  • View blog
  • Posts: 4,181
  • Joined: 14-February 08

Re: Problem using SDL_FreeSurface

Posted 21 July 2014 - 07:32 AM

You are most likely attempting to free an already freed surface. Check for null first

if(message != null)
{
  SDL_FreeSurface(message);
}


Was This Post Helpful? 0
  • +
  • -

#3 Peter O  Icon User is offline

  • D.I.C Head

Reputation: 77
  • View blog
  • Posts: 182
  • Joined: 19-October 13

Re: Problem using SDL_FreeSurface

Posted 21 July 2014 - 08:01 AM

Freeing a surface will not automatically set the pointer to null so you would have to do that yourself.
SDL_FreeSurface(message);
message = NULL;


Passing a null pointer to SDL_FreeSurface is fine and will do nothing, but in other parts of your program you probably should check if the pointer is null before trying to access the surface. Passing a null surface pointer to SDL_BlitSurface is not "safe".
Was This Post Helpful? 0
  • +
  • -

#4 migcak  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 45
  • Joined: 15-August 12

Re: Problem using SDL_FreeSurface

Posted 22 July 2014 - 09:51 PM

I changed my code like it was suggested but it still has issues. The game doesn't freeze right now, but the message and the button are still around when it should be deleted. The Tic-Tac-Toe game board does show up like I want. I tried rearranging where I called apply_surface(0, 0, background, screen) and apply_surface(75, 150, message, screen) in my main function but the game board wouldn't show up.

I also made a game log to keep track of what is happening when I call handle_input() and deleting the message and button as well as applying the Tic-Tac-Toe game board. Here is the text file Attached File  log.txt (3.08K)
Number of downloads: 16


Here is some more code (and old code) that should be useful for the problem.
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include <string>
#include <fstream>
using namespace std;

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 520;
const int SCREEN_BPP = 32;

SDL_Surface *background = NULL;
SDL_Surface *message = NULL;
SDL_Surface *button = NULL;
SDL_Surface *board = NULL;
SDL_Surface *screen = NULL;

SDL_Color textColor = {0, 0, 0};

TTF_Font *font = NULL;

SDL_Event event;

ofstream logger("log.txt");

void log(string message)
{
	logger << message << endl;

	logger.flush();
}

//More functions here but I don't think they have anything to do with this problem 

void Button::handle_input()
{
	int x = 0, y = 0;

	if(event.type == SDL_MOUSEBUTTONDOWN)
	{
		if(event.button.button == SDL_BUTTON_LEFT)
		{
			x = event.button.x;
			y = event.button.y;
		}

			if((x > box.x) && (x < box.x + box.w) && (y > box.y) && (y < box.y + box.h))
			{
				log("Message delete");
				if(message != NULL)
					SDL_FreeSurface(message);

				message = NULL;

				log("Button delete");
				if(button != NULL)
					SDL_FreeSurface(button);

				button = NULL;

				log("Apply game board");
				apply_surface(0, 0, board, screen);
			}
	}
}

void Button::show()
{
	apply_surface(box.x, box.y, button, screen);
}

int main(int argc, char* args[])
{
	bool quit = false;

	Button myButton(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 200, 125);

	if(init() == false)
		return 1;

	if(load_files() == false)
		return 1;

	message = TTF_RenderText_Solid(font, "Welcome to my Tic Tac Toe Game", textColor);

	if(message == NULL)
		return 1;

	apply_surface(0, 0, background, screen);
	apply_surface(75, 150, message, screen);


	while(quit == false)
	{
		if(SDL_PollEvent(&event))
		{
			log("Calling handle_input");
			myButton.handle_input();

			if(event.type == SDL_QUIT)
				quit = true;
		}

		myButton.show();

		if(SDL_Flip(screen) == -1)
			return 1;
	}

	clean_up();

	return 0;
}


Was This Post Helpful? 0
  • +
  • -

#5 Peter O  Icon User is offline

  • D.I.C Head

Reputation: 77
  • View blog
  • Posts: 182
  • Joined: 19-October 13

Re: Problem using SDL_FreeSurface

Posted 23 July 2014 - 01:05 AM

I hope you check if the surface passed to apply_surface is null before passing it to SDL_BlitSurface.

If you don't draw anything on top of where you drew the button it will still show even if you stop drawing it. You probably should draw the background just before calling myButton.show();

This post has been edited by Peter O: 23 July 2014 - 01:06 AM

Was This Post Helpful? 0
  • +
  • -

#6 migcak  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 45
  • Joined: 15-August 12

Re: Problem using SDL_FreeSurface

Posted 23 July 2014 - 10:09 AM

View PostPeter O, on 23 July 2014 - 01:05 AM, said:

I hope you check if the surface passed to apply_surface is null before passing it to SDL_BlitSurface.

If you don't draw anything on top of where you drew the button it will still show even if you stop drawing it. You probably should draw the background just before calling myButton.show();

I am checking to see if the surfaces are null. I have a loading function that returns false if the surface is null
bool load_files()
{
	background = load_image("Lightbackground.png");

	board = load_image("tic-tac-toe-board.png");

	button = load_image("Fplaybutton.bmp");

	font = TTF_OpenFont("lazy.ttf", 30);

	if(background == NULL)
		return false;

	if(board == NULL)
		return false;

	if(button == NULL)
		return false;

	if(font == NULL)
		return false;

	return true;
}


I tried to redraw the background right before myButton.show() but that didn't quite work, though I used your idea and put it somewhere else and it did work. I redrew the board right before I put the game board on the screen in handle_input().

here's what it looks like

void Button::handle_input()
{
	int x = 0, y = 0;

	if(event.type == SDL_MOUSEBUTTONDOWN)
	{
		if(event.button.button == SDL_BUTTON_LEFT)
		{
			x = event.button.x;
			y = event.button.y;
		}

			if((x > box.x) && (x < box.x + box.w) && (y > box.y) && (y < box.y + box.h))
			{
				log("Message delete");
				if(message != NULL)
					SDL_FreeSurface(message);

				message = NULL;

				log("Button delete");
				if(button != NULL)
					SDL_FreeSurface(button);

				button = NULL;

                //placing it here seems to work
				apply_surface(0, 0, background, screen); 

				log("Apply game board");
				apply_surface(0, 0, board, screen);
			}
	}
}

void Button::show()
{
	apply_surface(box.x, box.y, button, screen);
}

int main(int argc, char* args[])
{
	bool quit = false;

	Button myButton(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 200, 125);

	if(init() == false)
		return 1;

	if(load_files() == false)
		return 1;

	message = TTF_RenderText_Solid(font, "Welcome to George's Tic Tac Toe Game", textColor);

	if(message == NULL)
		return 1;

	apply_surface(0, 0, background, screen);
	apply_surface(75, 150, message, screen);

	while(quit == false)
	{
		if(SDL_PollEvent(&event))
		{
			log("Calling handle_input");
			myButton.handle_input();

			if(event.type == SDL_QUIT)
				quit = true;
		}

		myButton.show();

		if(SDL_Flip(screen) == -1)
			return 1;
	}

	clean_up();

	return 0;
}

Was This Post Helpful? 0
  • +
  • -

#7 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 204
  • Joined: 23-May 09

Re: Problem using SDL_FreeSurface

Posted 31 July 2014 - 02:12 AM

what is this, and why does it come before init() ?

Button myButton(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 200, 125);


is this another class that you haven't posted? is this all of your code?
Was This Post Helpful? 0
  • +
  • -

#8 migcak  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 45
  • Joined: 15-August 12

Re: Problem using SDL_FreeSurface

Posted 03 August 2014 - 05:19 PM

Sorry for late response, it is part of another class. I didn't show all the code. I got another problem turning the game into a two-player game so I'm going to post another question.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1