Issue with runtime error

Started by
4 comments, last by Nanoha 8 years, 1 month ago

Hey guys I am having an issue where my program is crashing and it compiles fine, I think it's an issue with composition but I am not sure, if you could help me out, I've been stuck on it for almost a week now, I would super dooper appreciate it. An explanation of the issue is included in the pastebin above the code.

http://pastebin.com/8YR8jmA2

thanks

learnedseeker

Advertisement
That's sounds like a perfect place to learn about debugging. Since you are not saying anything about your build environment or your IDE there is little specific to say but the problem should be easy to find by looking at the stack trace when the crash happens and then by homing in on it with a few breakpoints and stepping through the code while examining the state.

This is not necessarily your problem but:


    //Init SDL
    SDL_Init(SDL_INIT_EVERYTHING);
    if (!SDL_INIT_EVERYTHING) {
        ErrorCore("Failed to Initialize SDL.");
    }

That If will always be false (well unless that constant is 0). You should do this (according to the documentation http://sdl.beuc.net/sdl.wiki/SDL_Init):


if(0 != SDL_Init(SDL_INIT_EVERYTHING))
   // Failed

you should check the return value of this and make sure it isn't NULL:


renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

I would also reccomend you change graphicsCore_INIT to return true or false and use that further up too.

?In your EngineCore you are creating a player using new but you are not deleting it in the destructor.

I do believe your problem lies here:


Sprite::Sprite() {}

You create the player twice, once you create it with the default constructor which is the one you are actually using. That default constructor does nothing which means you have dangling undefined pointers. One of those is the inputcore variable which you later try to use (which crashes).

There are seriously issues throughout this code, I recommend you take some time to clean it up and make it more robust before doing anything else. Ensure you check return values where appropriate, any time you create an object with 'new' it must have a matching delete. Make sure all your constructors set sensible values for the objects variables. If your sprite class' default constructor actually set every pointer to NULL then you would have found this problem right away with a debugger, as it happens dangling/undefined pointers are much harder to catch.


EngineCore::EngineCore(bool *quit, Sprite* _passed_Player, IOCore* _passed_iocore,
    GraphicsCore* _passed_graphicscore, AudioCore* _passed_audiocore, Timer* _passed_timer) {
 
    player = new Sprite; // Default constructor!!!
    std::cout << "EngineCore init" << std::endl;
}

Sprite::Sprite() {} // This does not initialise any variables

player->inputcore->processInput(); // inputcore is undefined

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

That's sounds like a perfect place to learn about debugging. Since you are not saying anything about your build environment or your IDE there is little specific to say but the problem should be easy to find by looking at the stack trace when the crash happens and then by homing in on it with a few breakpoints and stepping through the code while examining the state.

Sounds about right. Do you recommend any programs and or tutorials for this issue (I don't even know what exactly I should google)? I'm using Visual Studio community edition... So I doubt it'll have many debugging bells and whistles.

This is not necessarily your problem but:


    //Init SDL
    SDL_Init(SDL_INIT_EVERYTHING);
    if (!SDL_INIT_EVERYTHING) {
        ErrorCore("Failed to Initialize SDL.");
    }

That If will always be false (well unless that constant is 0). You should do this (according to the documentation http://sdl.beuc.net/sdl.wiki/SDL_Init):


if(0 != SDL_Init(SDL_INIT_EVERYTHING))
   // Failed

you should check the return value of this and make sure it isn't NULL:


renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

I would also reccomend you change graphicsCore_INIT to return true or false and use that further up too.

?In your EngineCore you are creating a player using new but you are not deleting it in the destructor.

I do believe your problem lies here:


Sprite::Sprite() {}

You create the player twice, once you create it with the default constructor which is the one you are actually using. That default constructor does nothing which means you have dangling undefined pointers. One of those is the inputcore variable which you later try to use (which crashes).

There are seriously issues throughout this code, I recommend you take some time to clean it up and make it more robust before doing anything else. Ensure you check return values where appropriate, any time you create an object with 'new' it must have a matching delete. Make sure all your constructors set sensible values for the objects variables. If your sprite class' default constructor actually set every pointer to NULL then you would have found this problem right away with a debugger, as it happens dangling/undefined pointers are much harder to catch.

Oh i know there are issues, one I get this taken care of, I am going to do some cleaning.

I cannot get the Sprite in some areas to accept the parameters from the constructor, I am not sure why it won't eat the parameters, will check on that and see. I think that might be something I need some help with.

I didn't delete it because I can't even get it to work yet. =)

I took this to the after school help area and they couldn't help me, it's really hard to learn this stuff, even if your going to school for it, which is why I am doing this whole thing in the first place... Programming class in school teaches you how to crawl, and they pretty much expect you to be a marathon runner by the time you get a job, so here I am trying to get on two feet. Programming is really something you need a mentor for more than a 25 person class. =\

Thanks for the help so far.

Oh i know there are issues, one I get this taken care of, I am going to do some cleaning.
The other way around is more effective. Who knows, this may point you to the cause of the crash.

I don't know visual studio, but what happens if you run the program in the debugger? Most debuggers will catch the crash, and drop you into a state where you can analyze what the program was doing at the time.

You are using Visual Studio community edition? In that case you pretty much have one of the best IDEs already so that's a great start. To run with debugging just hit F5. To put down a breakpoint (so it will stop and let you look at what is going on while running) click a line and press F9. You can then press F10 to move along one step at a time.

c++ is a hard language to learn initially as there are so many places where you can go wrong, hopefully it will help if I clarify the issue you currently have.


class Sprite
{
public:
    Sprite();
    Sprite(SDL_Renderer* renderer, InputCore* inputcore, std::string FilePath, int x, int y, int w, int h);
    ~Sprite();
    InputCore* inputcore;
};

That is a trimmed down version of your sprite class. The default constructor is the one that takes no parameters.

In EngineCore you create a player:

player = new Sprite;

Because you have not provided any values to the constructor it decides to use the default constructor but when you look at the code for that it is:


Sprite::Sprite() 
{
}

It doesn't really do anything (your other constructor does though). So you have a bunch of variables one being inputCore that are not initialised, when something isn't initialised it could quite literally be anything. In a debug build it will usually get initialised to 0/null but in a release build it will be totally undefined. Later on you then attempt to use that variable but since it was never created and is completely random it causes your crash.

You need to do at least 2 things, first you need to make that constructor initialise sensible values:


Sprite::Sprite()
{
    image = nullptr;
    renderer = nullptr;
    inputcore = nullptr;
    posX = 0;
    posY = 0;
}

And secondly you need to get the part where you create the object to use the correct constructor, you can do that by passing it values:

player = new Sprite(renderer, NULL, "C:\\Users\\Devlin\\Documents\\Visual Studio 2015\\Projects\\Project Flesh\\Dependencies\\bob.png", 300, 250, 50, 100);

Be careful though because you have player in two places, delete the one you don't need; probably the one from graphics_core.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

This topic is closed to new replies.

Advertisement