Advertisement

[SDL] Continuing to run after termination

Started by July 27, 2011 02:31 PM
3 comments, last by MottMan 13 years, 4 months ago
I'm having a very strange problem where my program terminates (the window closes) but the program is still being ran. I have narrowed this down due to a second obstacle being created (as when it is commented out the program terminates properly) but I have no clue as to why.

main.cpp


#include "file_handling.h"
#include "maintenance.h"
#include "timer.h"
#include "objects.h"
#include "globals.h"
#include <list>

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

if (!init())
return 0;

std::list <Obstacle> ALL_OBSTACLES;
Obstacle wall(250, 125, 85, 140, "wall.bmp");
// Obstacle another_wall(100, 300, 85, 140, "wall.bmp"); <--- this is causing the problem!!@#!@
ALL_OBSTACLES.push_front(wall);
// ALL_OBSTACLES.push_front(another_wall);

Player character(0, 0, PLAYER_WIDTH, PLAYER_HEIGHT, "player.bmp");

Timer fps;

if (!load_files())
return 0;

while (quit == false)
{
while (SDL_PollEvent(&event))
{
character.handle_input();

if (event.type == SDL_QUIT)
quit = true;
}
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) );
character.move(ALL_OBSTACLES);
character.show();
wall.show();
// another_wall.show();
SDL_Flip(screen);

if (fps.get_ticks() < 1000 / FRAMES_PER_SECOND)
SDL_Delay((1000/FRAMES_PER_SECOND) - fps.get_ticks());
}

//keepWndow();
clean_up();

return 0;
}



objects.h

#ifndef OBJECTS_H_INCLUDED
#define OBJECTS_H_INCLUDED

#include "file_handling.h"
#include "collision_detection.h"
#include "globals.h"
#include "SDL/SDL.h"

#include <list>
#include <string>
#include <fstream>

//////////////////
/////OBSTACLE/////
//////////////////

class Obstacle
{
public:
Obstacle(int x, int y, int w, int h, std::string filename);
~Obstacle();

SDL_Rect obstacle_outline;
int segment;

void update_obsSeg();
void show();

private:
SDL_Surface *obstacle;
};

Obstacle::Obstacle(int x, int y, int w, int h, std::string filename)
{
obstacle = load_image(filename.c_str());

obstacle_outline.x = x;
obstacle_outline.y = y;
obstacle_outline.w = w;
obstacle_outline.h = h;

update_obsSeg();
}

Obstacle::~Obstacle()
{
SDL_FreeSurface(obstacle);
}

void Obstacle::show()
{
apply_surface(obstacle_outline.x, obstacle_outline.y, obstacle, screen);
}

void Obstacle::update_obsSeg()//Used in constructor
{
segment = segment_update(obstacle_outline);
}

#endif // OBJECTS_H_INCLUDED



If anyone has any idea of suggestions to try to fix the problem it would be much appreciated. Thanks in advance.
I don't know what causes the problem but I found another problem with that code. When you add an Obstacle object to ALL_OBSTACLES the object will be copied (using the copy constructor). This will result in two Obstacle copies having their SDL_Surface* pointing to the same surface. You will then have problems like dangling pointers and two calls to SDL_FreeSurface.
Advertisement
How do I prevent that from happening?
If you want to be able to copy Obstacle objects you can implement the copy constructor and the copy assignment operator.

Obstacle::Obstacle(const Obstacle& o)
{
*this = o;
}

Obstacle& Obstacle::operator=(const Obstacle& o)
{
obstacle_outline = o.obstacle_outline;
segment = o.segment;
obstacle = o.obstacle;
obstacle->refcount++;
return *this;
}
In the copy constructor we reuse the code from operator=. In operator= we copy all the members like the default operator= would do but we also increment the surface's refcount. This will work because SDL_FreeSurface will automatically decrement the refcount and only free the surface when the refcount reach zero.

If you instead don't want to allow copying Obstacle objects you can make the copy constructor and the copy assignment operator private. Then you can't store Obstacle in std::list (unless you use C++0x and std::move). You can instead store pointers or something like that: std::list <Obstacle*>.
I'll probably go the pointer route as it isn't really necessary for me to have copies (I don't use STL containers like list often so I learned something new).

Thanks for your help. Fingers crossed that also solves my other problem.

This topic is closed to new replies.

Advertisement