Advertisement

[sfml] Process is still running after window has been closed

Started by June 02, 2015 06:44 PM
7 comments, last by Esentiel 9 years, 7 months ago

Hello gentlemen

I'm faced with an annoying issue which drives so mad, that came here to ask an advice.

First of all, English is not my native language, so apologize if I messed up smile.png

Here is my code of a simple Pong game:

[spoiler]


#include <SFML/Graphics.hpp>

using namespace sf;

int const w = 800;
int const h = 600;

class Ball
{
public:
float dx, dy;
FloatRect rect;
Sprite sprite;

Ball(Texture &image)
{
dx, dy = -10;
sprite.setTexture(image);
rect = FloatRect(w, (rand() % 500) * 10, 10, 10);
}

void update()
{
rect.top += dy;
rect.left += dx;
sprite.setPosition(rect.left, rect.top);
}

};

class Player
{
public:
float dy;
FloatRect rect;
Sprite sprite;
bool isMoveUp;
bool isMoveDown;

Player(Texture &image)
{
sprite.setTexture(image);
rect = FloatRect(0, h / 2, 32, 128);
dy = 10;
isMoveUp = false;
isMoveDown = false;
}

void update()
{
sprite.setPosition(rect.left, rect.top);
}

void movePlayer(char direction)
{
if (direction == 'U')
{
if (rect.top>0)
rect.top -= dy;
}
else if (direction == 'D')
{
if (rect.top + rect.height < h)
rect.top += dy;
}
}

};

int main()
{

Texture playerTexture;
if (!playerTexture.loadFromFile("player.png"))
{
return 1;
}

Texture ballTexture;
if (!ballTexture.loadFromFile("ball.png"))
{
return 1;
}

Player * player = new Player(playerTexture);

Ball * ball = new Ball(ballTexture);

RenderWindow window(VideoMode(w, h), "The Pong game");
window.setFramerateLimit(60);
while (window.isOpen())
{

Event event;
while (window.pollEvent(event))
{
if (event.type == Event::Closed)
{
window.close();
{
delete[] ball, player;
break;
}
}

if (event.type == Event::KeyPressed)
{
if (event.key.code == Keyboard::Down)
{
player->isMoveDown = true;
player->isMoveUp = false;
}

if (event.key.code == Keyboard::Up)
{
player->isMoveUp = true;
player->isMoveDown = false;
}

}

if (event.type == Event::KeyReleased)
{
if (event.key.code == Keyboard::Down)
player->isMoveDown = false;

if (event.key.code == Keyboard::Up)
player->isMoveUp = false;

}

}
if (player->isMoveDown)
{
player->dy = 10;
player->movePlayer('D');
}

if (player->isMoveUp)
{
player->dy = 10;
player->movePlayer('U');
}

if (ball->rect.intersects(player->rect))
{
ball->dx = 10;
}

if (ball->rect.left >= w)
{
ball->dx = -10;
}
if (ball->rect.top >= h)
{
ball->dy = -10;
}
if (ball->rect.top <= 0)
{
ball->dy = 10;
}

window.clear(Color::Black);

ball->update();
player->update();

window.draw(player->sprite);
window.draw(ball->sprite);

window.display();
}

return 0;

}

[/spoiler]

Issues:

1. Before I created both player and ball in heap and delete[] them after window closed, program process remains running in system.

I'm not sure why do I have to have these objects in heap instead of stack.. and why the program behaves like that?

2. I'm trying to test the program in case images(textures) were not found. And you'll not believe me, the program remains running every single time I launch it.

Why return 1; hasn't killed the process?..

I'm a newbie to c++ and especially to c++ windows programming in visual studio[burn in hell VS!!! jk].

Spent much time googling, but it seems I can't even manage to perform a proper request.

PS: if it's possible, I would be very appreciate if you guys will be able to review my code and point me to weak parts.

Thank you in advance!

Hi,

first off, this does not work:


delete[] ball, player;

delete can only be used for a single pointer, not multiple pointers. What you are actually doing is using of the comma operator and then deleting just one pointer.

What does "the process remains running" mean? Is the Window not closing? Is it a console application and the console windows does not close? Can you still see the process running in the task manager but all windows are closed?

Advertisement

Hi,

first off, this does not work:


delete[] ball, player;

delete can only be used for a single pointer, not multiple pointers. What you are actually doing is using of the comma operator and then deleting just one pointer.

What does "the process remains running" mean? Is the Window not closing? Is it a console application and the console windows does not close? Can you still see the process running in the task manager but all windows are closed?

Hi,

Thanks for the answer.

By "process remains running" I mean I can see Pong.exe in the windows task manager while the only window is closed. I waited for awhile but it won't despair.

Hi,

morover this doesnt work either:


dx, dy = -10;

I would guess your problem is a runtime error. This has caused WerFault.exe firing up a few times already on my machine and then blocking the IDE.

Step through the code with a debugger and be sure to use the debug mode and read the logging in the console window. Maybe you are mixing code and binaries of different versions or debug and release mode?

Ok i just realized what your problem is.

When the Application receives a Closed event you are closing the window and deleting the ball and the player. Then you are using break to break out of the EventLoop but not out of the GameLoop! Later in the GameLoop you are using the now invalid pointers in your render code which is never a good idea :D

Fix it by moving the deletes below the GameLoop

Ok i just realized what your problem is.

When the Application receives a Closed event you are closing the window and deleting the ball and the player. Then you are using break to break out of the EventLoop but not out of the GameLoop! Later in the GameLoop you are using the now invalid pointers in your render code which is never a good idea biggrin.png

Fix it by moving the deletes below the GameLoop

Thank you for your advice related to pointers in rendering smile.png

I decided to get rid of them in my code. Also I purge int const(width, height) to be sure it's not related to the problem.

here is my current code:

[spoiler]


#include <SFML/Graphics.hpp>

using namespace sf;

class Ball
{
public:
	float dx, dy;
	FloatRect rect;
	Sprite sprite;

	Ball(Texture &image)
	{
		dx = -10;
		dy = -10;
		sprite.setTexture(image);
		rect = FloatRect(800, (rand() % 500) * 10, 10, 10);
	}
	void update()
	{
		rect.top += dy;
		rect.left += dx;
		sprite.setPosition(rect.left, rect.top);
	}
};

class Player
{
public:
	float dy;
	FloatRect rect;
	Sprite sprite;
	bool isMoveUp;
	bool isMoveDown;

	Player(Texture &image)
	{
		sprite.setTexture(image);
		rect = FloatRect(0, 600 / 2, 32, 128);
		dy = 10;
		isMoveUp = false;
		isMoveDown = false;
	}
	void update()
	{
		sprite.setPosition(rect.left, rect.top);
	}
	void movePlayer(char direction)
	{
		if (direction == 'U')
		{
			if (rect.top>0)
				rect.top -= dy;
		}
		else if (direction == 'D')
		{
			if (rect.top + rect.height < 600)
				rect.top += dy;
		}
	}
};


int main()
{
	Texture playerTexture;
	if (!playerTexture.loadFromFile("player.png"))
	{
		return 1;
	}

	Texture ballTexture;
	if (!ballTexture.loadFromFile("ball.png"))
	{
		return 1;
	}

	Player player(playerTexture);
	Ball ball(ballTexture);

	RenderWindow window(VideoMode(800, 600), "The Pong game");
	window.setFramerateLimit(60);
	while (window.isOpen())
	{
		Event event;
		while (window.pollEvent(event))
		{
			if (event.type == Event::Closed)
			{
				window.close();
				{
					break;
				}
			}

			if (event.type == Event::KeyPressed)
			{
				if (event.key.code == Keyboard::Down)
				{
					player.isMoveDown = true;
					player.isMoveUp = false;
				}

				if (event.key.code == Keyboard::Up)
				{
					player.isMoveUp = true;
					player.isMoveDown = false;
				}
			}

			if (event.type == Event::KeyReleased)
			{
				if (event.key.code == Keyboard::Down)
					player.isMoveDown = false;

				if (event.key.code == Keyboard::Up)
					player.isMoveUp = false;
			}

		}
		if (player.isMoveDown)
		{
			player.dy = 10;
			player.movePlayer('D');
		}

		if (player.isMoveUp)
		{
			player.dy = 10;
			player.movePlayer('U');
		}


		if (ball.rect.intersects(player.rect))
		{
			ball.dx = 10;
		}

		if (ball.rect.left >= 800)
		{
			ball.dx = -10;
		}
		if (ball.rect.top >= 600)
		{
			ball.dy = -10;
		}
		if (ball.rect.top <= 0)
		{
			ball.dy = 10;
		}

		window.clear(Color::Black);

		ball.update();
		player.update();

		window.draw(player.sprite);
		window.draw(ball.sprite);

		window.display();
	}

	return 0;

}

[/spoiler]

I double-checked libs and it seems there is no issue with that: debug libs for debug and common libs for release.

Also I checked warning during building the program.

1. is related to row: rect = FloatRect(800, (rand() % 500) * 10, 10, 10); //conversation from int to float

2. LNK4210: .CRT section exists; there may be unhandled static initializers or terminators E:\Documents\Visual Studio 2013\Projects\2D Games\ThePong\main.obj ThePong

3. LNK4210: .CRT section exists; there may be unhandled static initializers or terminators E:\Documents\Visual Studio 2013\Projects\2D Games\ThePong\MSVCRT.lib(atonexit.obj) ThePong

First one isn't seem to be a big deal. 2nd and 3rd I googled and it was related to [Config -> Linker -> Advanced -> Entry Point]. I set "main" there for a some reason.

And after I blank this field the problem wasn't reproduced.

As you mentioned in the first post: the root-cause was in the debug information smile.png

Thank you for help and useful advices!

PS: that's why I hate VS. it's like a space ship: can be powerful if you are familiar with it, or can ruin your day with a wrong property set.

Advertisement

Since you are using C++ and SFML on Windows, if you link to the sfml-main library you shouldn't have any main/starting point issues in your code. It should handle the conversion for you.

Also, you shouldn't need that break statement after

window.close();
. The example doesn't use it, and I've never had a need for it If you are running your program through VIsual Studio, that may be a potential reason for it staying open. Try running it without debugging and see what happens.
Actually the break is just breaking out of the event loop. As we want the application to close anyway I cant see a reason to keep processing any events. Of course its not a problem if we are not breaking out of the event loop as long as that doesnt mean processing on already deleted resources etc. But on the other hand the break wont do any harm either.

Since you are using C++ and SFML on Windows, if you link to the sfml-main library you shouldn't have any main/starting point issues in your code. It should handle the conversion for you.

Also, you shouldn't need that break statement after


window.close();
. The example doesn't use it, and I've never had a need for it If you are running your program through VIsual Studio, that may be a potential reason for it staying open. Try running it without debugging and see what happens.

Yes I included sfml-main.lib. It works great when you have no "entry point" set in projects settings. I tested it: with entry point = main - the program stays working in background; with empty entry point - the program is closed like it should be. Don't know the root cause of such behavior but it is the reason of my issue.

PS:

that break; was created in a desperation of mine :)

I tried everything I could find in google. and it was one of that things.

After your explanation I got it.

Thanks.

This topic is closed to new replies.

Advertisement