I've tried to read up on the difference between return EXIT_SUCCESS; from main() and calling exit(EXIT_SUCCESS) from anywhere, and the best resource I've found so far is this answer here on SO. However, there is one detail I'd like to have cleared up.
To me, the most compelling argument against exit() (as laid forward in that post) is that no destructor is called on locally scoped objects. But what does this mean to other objects? What if I'm calling exit() from somewhere else, quite far away on the stack from the main() method, but in block (even a method) that contains only that call, and no variables? Will objects elsewhere on the stack still be destructed?
My use case is this:
I have an application that keeps prompting the user for input until the "quit" command is given (a text-based adventure game). The easiest way to accomplish that, was to map "quit" to a method that simply calls exit(EXIT_SUCCESS). Of course, I could write it so that every action the user can take returns a boolean indicating wether the game should go on or not, and then just return false when I want to quit - but the only time I'd return anything but true is from this method - every other action method would then have to return true just because I wanted to avoid exit(). On the other hand, I create quite a lot of objects and allocate quite a lot of memory dynamically - all of that has to be taken care of by class destructors, so it is crucial that they do run.
What is best practice here? Is this a good case for exit(), or just as bad as in the main method?
if (command == "quit") {
throw QuitGameException();
}
You could throw an exception. An exception would safely unwind the stack and destroy objects in all the callers along the way.
I'm not even gonna read that SO post, because I know what it says. Don't use exit(), so don't.
I know one reason to use exit() - if you're completely doomed anyway and there's no way you can exit nicely. In such case you will not exit with code zero. So, exit() with non-zero when you're about to crash anyway.
In every other case, create variables which let you leave main loops and exit main nice and sane, to clean-up all your memory. If you don't write code like this, you will e.g. never be able to detect all your memory leaks.
Will objects elsewhere on the stack still be destructed?
Nope, exit() does the following (in order):
Objects associated with the current thread with thread storage duration are destroyed (C++11 only).
Objects with static storage duration are destroyed (C++) and functions registered with atexit are called (if an unhandled exception is thrown terminate is called).
All C streams (open with functions in ) are closed (and flushed, if buffered), and all files created with tmpfile are removed.
Control is returned to the host environment
from: http://www.cplusplus.com/reference/cstdlib/exit/
exit() does not unwind the stack, the memory for the whole stack is simply freed, the destructor for individual objects in the stack are not run. Using exit() is safe only when all objects that does not have simple destructors (those that does not deal with external resources) are allocated in the static storage (i.e. global variables or locally scoped static variable). Most programs have files handlers, socket connections, database handlers, etc that can benefit from a more graceful shut down. Note that dynamically allocated object (that does not deal with external resources) does not necessarily need to be deallocated because the program is about to terminate anyway.
exit() is a feature inherited from C, which does not have destructor and so clean up of external resources can always be arranged using atexit(); in general it's very hard to use exit() in C++ safely, instead in C++ you should write your program in RAII, and throw an exception to terminate and do clean ups.
Related
I'm calling a function fooA from main() that calls another function fooB that is recursive.
When I wish to return, I keep using exit(1) to halt execution. What is the right way to exit when the recursion tree is deep?
Returning through the recursion stack may not be of help because returning usually clears a part solution I build and I don't want to do that. I want to do execute more piece of code from main().
I read Exceptions can be used, it would be nice if I can get a code snippet.
The goto statement won't work to hop from one function back to another; Nikos C. is correct that it wouldn't account for releasing the stack frames of each of the calls you've made, so when you got to the function you goto'ed to, the stack pointer would be pointing to the stack frame of the function you were just in... no, that just won't work. Similarly, you can't simply call (either directly, or indirectly via a function pointer) the function you want to end up in when your algorithm is done. You'd never get back to the context you were in prior to diving into your recursive algorithm. You could conceivably architect a system this way, but in essence each time you did this you'd "leak" what was currently on the stack (not quite the same as leaking heap memory, but a similar effect). And if you were deep into a highly recursive algorithm, that could be a lot of "leaked" stack space.
No, you need to somehow return back to the calling context. There are only three ways to do so in C++:
Exit each function in turn by returning from it to its caller
backing up through the call chain in an orderly fashion.
Throw an exception and catch it at the point right after you
launched into your recursive algorithm (which automatically destroys
any objects created by each function on the stack in an orderly
fashion).
Use setjmp() & longjmp() to do something similar to throwing &
catching an exception, but "throwing" a longjmp() will not destroy
objects on the stack; if any such objects own heap allocations,
those allocations will be leaked.
To do option 1, you have to write your recursive function such that once a solution is reached, it returns some sort of indication that it's complete to its caller (which may be the same function), and its caller sees that fact & relays that fact on to its caller by returning to it (which may be the same function), so on and so on, until finally all stack frames of the recursive algorithm are released and you return to whatever function called the first function in the recursive algorithm.
To do option 2, you wrap the call to your recursive algorithm in a try{...} and immediately after it you catch(){...} the expected thrown object (which could conceivably be the result of the computation, or just some object that lets the caller know "hey, I'm done, you know where to find the result"). Example:
try
{
callMyRecursiveFunction(someArg);
}
catch( whateverTypeYouWantToThrow& result )
{
...do whatever you want to do with the result,
including copy it to somewhere else...
}
...and in your recursive function, when you finish the results, you simply:
throw(whateverTypeYouWantToThrow(anyArgsItsConstructorNeeds));
To do option 3...
#include <setjmp.h>
static jmp_buf jmp; // could be allocated other ways; the longjmp() user just needs to have access to it.
.
.
.
if (!setjmp(jmp)) // setjmp() returns zero 1st time, or whatever int value you send back to it with longjmp()
{
callMyRecursiveFunction(someArg);
}
...and in your recursive function, when you finish the results, you simply:
longjmp(jmp, 1); // this passes 1 back to the setjmp(). If your result is an int, you
// could pass that back to setjmp(), but you can't pass zero back.
The bad thing about using setjmp()/longjmp() is that if there are any stack-allocated objects still "alive" on the stack when you call longjmp(), execution will jump back to the setjmp() point, skipping the destructors for those objects. If your algorithm uses only POD types, that's not an issue. It's also not an issue if the non-POD types your algorithm uses do NOT contain any heap allocations (e.g. from malloc() or new). If your algorithm uses non-POD types that contain heap allocations, then you're only safe with options 1 & 2 above. But if your algorithm meets the criteria of being OK with setjmp()/longjmp(), and if your algorithm is buried under a ton of recursive calls at the point it finishes, setjmp()/longjmp() may be the fastest way back to the initial calling context. If that won't work, option 1 is probably your best bet in terms of speed. Option 2 may seem convenient (and would possibly eliminate a condition check at the start of each recursion call), but the overhead associated with the system automatically unwinding the callstack is somewhat significant.
It's typically said you should reserve exceptions for "exceptional events" (events expected to be very rare), and the overhead associated with unwinding the callstack is why. Older compilers used something akin to setjmp()/longjmp() to implement exceptions (setjmp() at the location of the try & catch, and longjmp() at the location of a throw), but there was of course extra overhead associated with determining what objects on the stack need destroyed, even if there are no such objects. Plus, every time you'd run across a try, it would have to save the context just in case there was a throw, and if exceptions are truly exceptional events, the time spent saving that context was simply wasted. Newer compilers are now more likely to use what are known as "Zero Cost Exceptions" (a.k.a. Table Based Exceptions), which seems like that would solve all the world's problems, but it doesn't.... It makes normal runtime faster because there is no longer a need to save the context every time you run across a try, but in the event that a throw executes, there is now even more overhead associated with decoding information stored in massive tables that the runtime has to process in order to figure out how to unwind the stack based on the location where the throw was encountered and content of the runtime stack. So exceptions aren't free, even though they're very convenient. You'll find a lot of stuff on the internet where people make claims about how unreasonably expensive they are and how much they slow down your code, and you'll also find lots of stuff by people refuting those claims, with both sides presenting hard data to bolster their claims. What you should take away from the arguments is that using exceptions is great if you expect them to rarely occur, because they result in cleaner interfaces & logic that's free of a ton of condition checking for "badness" every time you make a function call. But you shouldn't use exceptions as a means of normal communication between a caller and its callees, because that mode of communication is significantly more expensive than simply using return values.
This happened to me while finding the path from root to node of a binary tree. I was using a stack to store the nodes in preorder and the recursion wouldnt stop until the last node returned NULL. I used a global variable, integer i=1, and when I reached the node I was looking for I set that variable to 0 and used while(i==0) return stack; to allow the program to go back up the memory stack without popping my nodes off.
I've got a class that collects and processes some data during the execution of the program, let's call it dataCollectionInterface. When the program terminates (or rather: a dataCollectionInterface object goes out of scope) some final processing and output of (some of) the collected data needs to be done.
The question now is: should I put this final processing and output (to files) into the destructor of dataCollectionInterface (or call it from within the destructor)? Or should I provide a public member routine (doFinalProcessing) that needs to be explicitly called by the main program?
Putting it into the destructor would be a lot more convenient (no need to worry about safeguards against data modulation after a call to doFinalProcessing etc.), but are there downsides, e.g. with respect to the handling of possible exceptions from the output operations?
You should not be throwing any exceptions from the destructor, So better to do it in a public function, rather than the destructor if your operations can throw exceptions and you need to do the exception handling for them.
Though, If you can rather handle all your exceptions within the destrucotr itself without throwing them out from the destructor, then you might go for the first mechanism as well, I see no harm if you can reliably do so.
A destructor cannot fail. Thus, you should not put any operations which
might fail (and output can fail) in a destructor; what do you do if it
fails.
There are exceptions, when the operation isn't really relevant to the
overall functionality of the program (logging output, for example), or
when it is a safeguard (ofstream will close the file in the
destructor, ignoring any errors), or when it is part of an operation
which will be later "annulled": a non-committed transation may close an
output file, for example, knowing that because the transaction is not
committed, the file will later be deleted. But they are just that:
exceptions.
Others are correct about destructors not throwing, but that shouldn't mean not to do it in a destructor. Nor should it mean that there should be no diagnostics. But you definitely should put it in the destructor.
First of all, the reason that you should put it in the destructor is less about immediate convenience but because zombies are evil. Objects that have finished their useful lifetime but still exist to be accidentally encountered and used are the bane of developers. Young developers come in and touch them when they shouldn't causing all sorts of problems. Complexity explodes because you now have to check if you've cleaned up things properly. Exception handling is now not automatic, as it would be in a destructor. Do you really want to write try/catches everywhere you use the object just because something unrelated might throw and you have to clean it up properly? Do you want to write "ifs" in all your code for that class to make sure they aren't using a mostly dead object?
Two-phase initialisation or destruction are code smells that you are not using ctors/dtors correctly. Use them to automate all of your object's lifetime (RAII), and you will never have the code fragility that zombies bring.
So, how do you do it if the output operation might throw?
Wrap your use of possible throwing calls in a try / catch.
In the constructor of the object, take an optional function callback to an error handling routine from the user.
In the dtor, when an exception is caught, call the callback (if they gave you one) with whatever diagnostic you can provide
Wrap the callback call in a try/catch too, as you have no idea what others will do
Do nothing if the callback throws - they had their chance
It's really that simple. Don't ever let zombies roam, even if you have special exception-possible code in dtors. Instead, provide a means to handle that in an abstract manner. A single special case of cleanup is always better than the combinatorial explosion of special cases when zombies are let free.
I would provide both: destructor with some default behaviour (catching all exceptions and probably silent about possible problems) and a public member routine with extended diagnostics. What approach to use is up to user of the class. Internally the destructor may call the routine with try/catch block, if the routine may throw. The routine should be idempotent (second call should do nothing)
I am working on a school assignment, and we were told that whenever we have an input
error we should print a message and exit the program. Obviously I use exit(1), but
the problem is I have memory leaks when using this functions. I don't understand why - every single variable I've used was on the stack and not on the heap.
What should I do to prevent those memory leaks?
Thanks!
exit does not call the destructors of any stack based objects so if those objects have allocated any memory internally then yes that memory will be leaked.
In practice it probably doesn't matter as any likely operating system will reclaim the memory anyway. But if the destructors were supposed to do anything else you'll have a problem..
exit doesn't really mix well with c++ for this reason. You are better just allowing your program to return from main to exit, or if you need to exit from an internal function throwing an exception instead, which will cause the call stack to be unwound and therefore destructors to be called.
When using the exit function, your program will terminate and all memory allocated by it will be released. There will be no memory leak.
EDIT:
From your comments, I can understand you're concerned that your objects aren't destroyed before termination (i.e. their destructor isn't called). This however doesn't constitute a memory leak, since the memory is released by the process and made available to the system. If you're counting on object destructors to perform operations important to your workflow, I suggest returning an error code instead of using exit and propagate that error code up to main().
EDIT2:
According to the standard, calling exit() during the destruction of an object with static storage duration results in undefined behavior. Are you doing that?
The solution is to not use exit() at all. You write your program using RAII (use classes for resources management) and throw an exception when something goes wrong. Then all memory is reclaimed thanks to destructors being called.
You don't have a real memory leaks. When a program is terminate the OS freeing all the memory the program used.
I want to immediately exit my MFC app in C++. Is exit(0) the best solution? eg. does it prevent destructors from being called, is it threadsafe? etc. Is there a better solution? Thanks.
Yes, exit(0) is the best solution. It will cause the destructors of global objects (and static objects within functions) to run, however it will not cause destructors of stack-allocated or heap-allocated objects to run:
// At global scope
ClassWithDestruct globalObject;
void SomeFunction()
{
static ClassWithDestructor staticObject;
ClassWithDestructor stackObject;
ClassWithDestructor *heapObject = new ClassWithDestructor;
// On the following call to exit(), the destructors of 'globalObject' and
// 'staticObject' will run, but those of 'stackObject' and 'heapObject' will
// NOT run
exit(0);
}
As to whether or not it's thread-safe, that's a hard question to answer: you should not be calling exit simultaneously from multiple threads, you should only call it once. If any destructors run as a result of exit, or any if any functions registered with atexit run, then obviously those functions should be thread-safe if they deal with data that could potentially be being used by other threads.
If your program is exiting normally (say, as a result of the user requesting an exit), you should either call exit or return from main/WinMain, which is equivalent to calling exit. If your program is exiting abnormally (say, as a result of an access violation or failed assertion), you should call either _exit or abort, which do not call any destructors.
If you want to exit immediately, ensuring against running any destructors and such beforehand, then you probably want to call abort(). If you do want destructors to execute, then you probably want to use PostQuitMessage(0);. Either way, exit() is probably the wrong choice.
when a win32 process exits any resource associated with it is cleaned up by the OS, so in order to me it is perfectly ok.
exit(0) exits the process. All memory is cleaned up. On the other hand explicitly managed resources may not be closed. Of course file handles would be closed and stuff in windows buffers will be flushed. However stuff that the application manages will not.
No, it's not a safe way to end your program. Static-storage data and non-local automatic objects will destruct, but local automatic objects will not.
From 18.3/8 in the C++ standard:
The function exit() has additional
behavior in this International
Standard:
First, objects with static storage
duration are destroyed and functions
registered by calling atexit are
called. Non-local objects with static
storage duration are destroyed […].
(Automatic objects are not destroyed
as a result of calling
exit().)[207]) […] A local static
object obj3 is destroyed at the same
time it would be if a function calling
the obj3 destructor were registered
with atexit at the completion of the
obj3 constructor.
Next, all open C streams (as
mediated by the function signatures
declared in <cstdio>) with unwritten
buffered data are flushed, all open C
streams are closed, and all files
created by calling tmpfile() are
removed.[209])
[207]: Objects with automatic storage
duration are all destroyed in a
program whose function main()
contains no automatic objects and
executes the call to exit(). Control
can be transferred directly to such a
main() by throwing an exception that
is caught in main().
[209]: Any C streams associated with
cin, cout, etc (27.3) are flushed
and closed when static objects are
destroyed in the previous phase. The
function tmpfile() is declared in
<cstdio>.
On a related note, std::exit(EXIT_SUCCESS) is disturbingly misleading.
C++ automagically calls destructors of all local variables in the block in reverse order regardless of whether the block is exited normally (control falls through) or an exception is thrown.
Looks like the term stack unwinding only applies to the latter. How is the former process (the normal exit of the block) called concerning destroying local variables?
An object is automatically destructed when it "goes out of scope". This could be referred to as "automatic storage reclamation", but that actually refers to garbage collection (there are several papers with that phrase in their name that use the term to mean garbage collection). When it is used to ensure proper pairing of open/close, lock/unlock, or other forms of resource acquisition with their appropriate release, then it is known as the design pattern of Resource Acquisition is Initialization (RAII), which is somewhat ironic given that the main aspect of RAII is not the resource initialization or acquisition, but rather its destruction.
Stack unwinding happens in both these cases, it's just that under normal execution the stack is unwound only to the context of the calling method (or block) when the executing method returns (or the block is exited). Local variables are allocated on the stack, so they are cleaned up in reverse order of allocation, and it's this process that is called unwinding. It's no different than processing any other type of data that you'd store in a LIFO structure - e.g. undo, redo.
When an exception is thrown the handler will unwind the stack through through zero or more methods until it finds one that can catch the exception, or until it reaches the top of the stack, at which point the unhandled exception handler will be called.
It seems to be convention to only use the term stack unwinding in the case of exception handling, but it's the same process occurring in each of these cases. The specific case where the stack unwinds due to a method exiting is called returning, there doesn't seem to be any convention for naming what happens when a scoped block of code is exited.
The local variable is destroyed when it goes out of scope. Perhaps the process is called like "going out of scope"?
I'm not sure there is a name for this. Stack variables are so automatic that no one worries about them, ever, not even enough to give a name for this automatic cleanup process.
Call it "going out of scope", I guess.
I've always heard it spoken as "going out of scope" or more precisely "an auto variable going out of scope".
If what you're asking is how the method call is actually implemented in machine code, I would say it would depend on the calling convention used