Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Shutting down Allegro

This thread is locked; no one can reply to it. rss feed Print
Shutting down Allegro
gillius
Member #119
April 2000

It's time to ask a real question.

Do I really need to shutdown Allegro at the end of a program? Destroying all bitmaps, uninstalling all addons, etc.

It makes sense I need to call al_install_system (I'm not using C, so no atexit), and init all the addons like mouse, audio, etc. But, I have all of this code to track everything so I can destroy it on shutdown, uninstall the addons, and finally call al_uninstall_system.

Now I'm faced with a context where I might want two Allegro displays so if I coded each one independently I'd install Allegro and uninstall Allegro at the end, but now I actually need a "reference counting" system of sorts so I can install twice but need to uninstall twice before it's really uninstalled.

I try to be a great "C" programmer even though I'm not using C. For every X there is an equal but opposite reaction Y (al_malloc and al_free, install/uninstall, create/destroy), but I know the OS cleans all of this up for me.

Is it really worth it? Do I really need lines and lines of code at the end of main just to free/destroy/uninstall everything? Even if I have a little fear of a fault if accidentally cleaning up something twice? I know I'll probably get laughed off of the Internet for proposing malloc without free but do we REALLY need to?

Gillius
Gillius's Programming -- https://gillius.org/

Mark Oates
Member #1,146
March 2001
avatar

Honestly, I never really have.

Lately, this has affected me when doing a bunch of tests in rapid succession, in which I need to setup and breakdown Allegro for each test. This is manageable, but only because the setups and tear downs are minimal. I just recently added an issue to audit the Framework teardown which has, for years, not done anything at all. ;)

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

princeofspace
Member #11,874
April 2010
avatar

I do, but only because I think it's better engineering.

A while back I wrote a quick interface with a function pointer array and a couple of functions to add game startup/shutdown routines in pairs.

#SelectExpand
1 2bool kr_startup_pair_add(bool (*alpha)(void), void (*omega)(void)) 3{ 4 5 /* add one pair of commands -- one to execute at startup (alpha) -- right now, and 6 * one to execute as it's analog at shutdown (omega) 7 */ 8 9 if (omega) { 10 shutdown[count] = omega; 11 ++count; 12 } 13 if (alpha) { 14 if (!alpha()) 15 return false; 16 } else { 17 return false; 18 } 19 20 return true; 21 22}

At shutdown we run a function that does a quick loop through the array up to value "count" to execute the shutdown functions. Because they're added in the correct order, they're executed in the correct order.

Do you need to do this? Well, valgrind certainly complains a bit less when I shut things down the "right" way, and that helps me debug and check for memory leaks, just by simplifying the final memory check report. This alone makes it worthwhile for me, and it's not all that hard to do.

David Couzelis
Member #10,079
August 2008
avatar

Reasons why I clean up everything when my program exits:

  • Allegro is compiled for many, many operating systems. Linux (my development environment) may cleanup memory when an application exits, but I don't know if every operating system supported by Allegro does, and I don't want that to be a limiting factor for anyone who wants to port my software.

  • It's about control. If I'm not in complete control of memory when my application exits, do I really have good control of my memory when it's running? I really, REALLY do NOT want a memory leak. I actually (automatically) count the number of times malloc and free are called, and make sure they are equal on exit.

  • It's a fun challenge.

Hmmm... I guess that's all I can think of. ::)

RPG Hacker
Member #12,492
January 2011
avatar

In your own code, you can usually get away with not calling certain free/destroy functions if you know your game works fine without. This doesn't mean I recommend doing this, though. You never know who mind end up getting access to your code in, let's say, five or ten years. We're actually in the process of porting a game right now where the original developers probably something something similar. Something along the lines of "Oh well, it's just our own, internal code. It doesn't matter if it doesn't clean up properly as long as it doesn't break anything". Well, now we have that code and some of those memory leaks DID, in fact, cause problems. So in general, I don't recommend not calling all those cleanup functions. That's not only bad practice, but could actually break some things. Now for just testing something quickly, it probably doesn't matter whether you cleanup everything properly or not, but once you finalize some code, you should definitely make sure everything cleans up properly.

Now all of this goes for private code only. For public code, proper cleanup is definitely mandatory, since you never know who will use your code in the end and in what way.

gillius
Member #119
April 2000

Well I think about it this way, if I kill -9 the app, or it just crashes, then all memory is freed and you don't have like a random orphan display window hanging out.

And I'm not talking about not destroying things in the middle of the app. I'm not even talking about the fact that if someone calls "shutdown" on my framework that it should properly shutdown (I agree that it should). I'm talking about shutdown and destroy immediately before main (and the program) ends. So far the only real concern I see raised is if you were using a heap debugger like Valgrind, although that would be very unlikely applied by users of my current project (the Java binding to Allegro, jalleg).

Let's say I do shutdown, will al_uninstall_system automatically uninstall mouse, keyboard, etc. addons and al_destroy all bitmaps, samples, etc.? If so that of course dramatically reduces the effort, I can just call al_uninstall_system and al_free the few things I am forced to al_malloc in Allegro (memfiles and samples generated from my own buffers).

Gillius
Gillius's Programming -- https://gillius.org/

RPG Hacker
Member #12,492
January 2011
avatar

The problem with this aproach is that you need to know exactly what the code you're using does internally. Now for Allegro, this may be the case. But what if you're using a different library and don't know exactly about its inner workings? It may do something very important in the destructor that would be a bad idea to skip. For example, maybe some class decides to flush user data in its destructor and skipping that desctructor prevents the data from being saved. Unless you know exactly that a certain free function doesn't do something important, not calling it should definitely be avoided. Sure, closing the application will free all memory consumed by it, but freeing memory and calling a free function aren't the same thing. A free function could always do more stuff than just freeing your memory.

If you absolutely want to tie the lifetime of some data to your main() function, then that's what classes and local scopes are for. Just create a class that wraps your calls, create a local instance of that class in your main() function and now once you leave your main() function, the appropriate free function will automatically be called. Or if you need to work with new/delete, smart pointers are also a thing.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

For the most part you don't need to do this. al_install_system hooks the atexit routines to shut down allegro automagically. All displays are destroyed and then all bitmaps, etc..

Be paranoid about it if you want, but there is probably no issue at all.

David Couzelis
Member #10,079
August 2008
avatar

Wait, references to all the bitmaps created by Allegro are kept internally and deleted on exit?? :o

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Chris Katko
Member #1,881
January 2002
avatar

Even if Allegro didn't... the operating system is still going to...

Though, I'm not sure if GPU memory allocation is handled by the OS.

(I still free everything... when I remember.)

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

bamccaig
Member #7,536
July 2006
avatar

I think you're over-thinking the jallegro implementation. The complexity comes from trying to wrap up a C API into a Java API. It's lying to the user, and that comes with great complexity to get right on your end. The easier solution is to expose Allegro more purely and leave the user in charge of that. Sure, it might not be very Java-like, but they aren't using a Java library. They're using a Java-binding to a C library. To avoid unforeseen consequences I think that you should clean up after yourself. Whether that means the library or the program, whatever is making the mess should clean it up (or try to). :)

gillius
Member #119
April 2000

the jalleg binding itself is pure. It works just like real Allegro does except there is no al_init because there is no atexit, so user has to call al_uninstall_allegro directly. I have no questions about that. There's no "lying" going on it's a straight binding. I'm not trying to re-implement Allegro in Java or hide Allegro or hide that it's C or that it's not garbage collected.

(re atexit: actually there is a Java equivalent to atexit called a shutdown hook but I haven't fully investigated if the Allegro DLL is still guaranteed to be loaded at this time).

However, on top of the binding I am having some utility framework classes to initialize and shutdown Allegro for you, namely it remembers what addons are installed. Then it can uninstall them.

I think the topic has derived too much from the original question. It seems that the consensus is to make sure to call al_uninstall_allegro. In my examples program I'll just have to make sure not to call al_uninstall_allegro if another example is concurrently running in another display in the same process. That was really the point of the original question is if I needed to go through that effort (vs. the alternative of never calling uninstall). Since the current code already uninstalls addons I can just leave that even if not necessary.

Gillius
Gillius's Programming -- https://gillius.org/

Niunio
Member #1,975
March 2002
avatar

  • Allegro is compiled for many, many operating systems. Linux (my development environment) may cleanup memory when an application exits, but I don't know if every operating system supported by Allegro does, and I don't want that to be a limiting factor for anyone who wants to port my software.


  • It's about control. If I'm not in complete control of memory when my application exits, do I really have good control of my memory when it's running? I really, REALLY do NOT want a memory leak. I actually (automatically) count the number of times malloc and free are called, and make sure they are equal on exit.

I'm with David Couzelis. Even if Allegro and the OS handle everything, I prefer to do it by myself. It's just doing things the right way.

-----------------
Current projects: Allegro.pas | MinGRo

Go to: