Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Allegro 5 and shared_ptr: Crash on exit

Credits go to Elias and Kris Asick for helping out!
This thread is locked; no one can reply to it. rss feed Print
Allegro 5 and shared_ptr: Crash on exit
Fishcake
Member #8,704
June 2007
avatar

Anyone can figure out why this is crashing on exit (EXC_BAD_ACCESS)?

#SelectExpand
1Application::Application() { 2 3} 4 5Application::~Application() { 6 7 al_destroy_timer(timer); 8 al_destroy_event_queue(eventQueue); 9 al_destroy_display(display); 10 al_uninstall_system(); 11 12} 13 14void Application::init(int argc, 15 char **argv, 16 const std::string &configFilename) { 17 /* Initialize Allegro and everything */ 18} 19 20int Application::run() { 21 22 bool shouldExit = false; 23 al_start_timer(timer); 24 25 while (!shouldExit && gameStateManager->getActiveStateCount() > 0) { 26 /* Do stuff */ 27 } 28 29 al_stop_timer(timer); 30 31 return 0; 32} 33 34// ApplicationPtr is a typedef of std::shared_ptr<Application> 35// This is probably a bad way of doing singleton, but heck, 36// I'm rushing for Santahack! 37ApplicationPtr Application::GetInstance() { 38 static ApplicationPtr application = std::make_shared<Application>(); 39 return application; 40}

#include <allegro5/allegro.h>
#include "Application.h"

int main(int argc, char **argv) {
    
    ApplicationPtr app = Application::GetInstance();
    app->init(argc, argv, "data/config.ini");
    app->run();
    
    return 0;
    
}

I don't know how to get the stack trace in Xcode, so here's a screenshot of it instead. :P

{"name":"607036","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/9\/79870dd1522dad465e4890e48735dccc.png","w":339,"h":500,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/9\/79870dd1522dad465e4890e48735dccc"}607036

This is my first time using smart pointers.

Elias
Member #358
May 2000

My guess is you call Allegro functions after shutting down Allegro. By default Allegro gets shut down at the end of the main() function, but global destructors are called afterwards.

You could use al_install_system instead of al_init and pass your own atexit function to prevent the automatic shutdown at the end of main().

--
"Either help out or stop whining" - Evert

Kris Asick
Member #1,424
July 2001

Elias has got it right. If you want to continue making your program the way you are, you need to explicitly create and destroy your Application object in your main() procedure like this:

Application *myapp = new Application;

// Do Stuff

delete myapp;

This way, Allegro won't auto-shutdown after main() returns before your Application objects are destroyed. ALL objects with Allegro functions in them MUST be created explicitly for this reason.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Fishcake
Member #8,704
June 2007
avatar

Yes, you're right. I fixed it by using al_install_system, passing a dummy function as the second argument.

// I'm dumb!
int DummyExitFunction(void (*stuff)(void)) {
    return 0;
}

//...

al_install_system(ALLEGRO_VERSION_INT, DummyExitFunction);

I still don't get why the function needs to have that weird signature instead of just void (*)(void). But who cares for now, as long as it works! Thanks! ;D

Kris Asick
Member #1,424
July 2001

One big catch you may run into with your current approach is the order in which your objects are removed from memory, specifically if you place Allegro code into the destructors of even more implicitly declared objects. In this event, the order in which you create your objects will be important so that the one that actually shuts down Allegro in its destructor will be called last when your program exits.

Overall, it's still safer to explicitly declare any objects that have Allegro functions in their destructors. :P

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Go to: