Using exit and a global object - c++

I have the following program where i am calling exit() in the destructor. When i create an object of type sample inside main() destructor is called once and program exits normally. But when i create a global object of type sample, "Destructing.." gets printed infinitely. Can anyone please explain how?
#include "iostream"
#include "conio.h"
using namespace std;
class sample
{
public:
~sample() {
cout <<"Destructing.."<<endl;
exit(0);
}
};
sample obj;
int main()
{
getch();
}

What's happening is, the exit() function is getting the program to call destructors on all of the global objects. And since at the point where your class's destructor calls exit(1); the object is not yet considered to be destructed, the destructor gets called again, resulting in an infinite loop.
You could get away with this:
class sample {
bool exiting;
public:
sample() { exiting = false; }
~sample() {
cout << "Destructing.." << endl;
if(exiting) return;
exiting = true;
exit(0);
}
};
But having a destructor call exit() is a Bad Idea. consider one of these alternatives:
create a separate normal (non-destructor) method for exiting
create a function that runs until the "program" is finished and call it from main()
use abort() instead of exit() (Thanks goldilocks for mentioning this one). abort() bypasses all of the cleaning up that is normally done when exit() is called and when main() returns. However this is not necessarily a good idea either, as certain cleanup operations in your program could be quite critical. abort() is meant only for errors that are already so bad that bypassing cleanup is warranted.
I suggested exceptions before but remembered about throwing exceptions from inside destructors and changed my mind. here's why.
Note also, the behavior is not consistent - some compilers/environments result in an infinite loop, some don't. It comes down to at which point in the destructor the object is considered to be destroyed. I would guess the standard either doesn't cover this or says the behavior in this case is undefined.

I agree with Micheal Slade that doing that in a destructor is a sign of bad design. But if you think you have a good reason to do so (eg, development issue), use abort() instead of exit(0). This will prevent any more destructors from being called and get you out of the recursive loop.

Your destructing destructor calls exit which in turn calls the destruction destructor which calls exit which in turn calls ... (Yes, it goes on for a very long time).

Related

How to destroy local variables if exceptions thrown by a function may be uncaught?

When a function throws while the exception is uncaught, stack unwinding is unlikely to trigger, so destructors of local variables won't be called. For example, the following code outputs only "created" (and the error messages) under g++ 7.1.0:
#include <iostream>
using namespace std;
struct A {
A() { cerr << "created\n"; }
~A() { cerr << "destroyed\n"; }
};
void f() {
A a;
throw 0;
}
int main() {
f();
}
This may lead to memory leaks upon crashing if A allocates memory, and whether the memory will be freed depends on the OS.
A possible solution I find is wrap f() in a function try-catch block:
void f() try {
A a;
throw 0;
} catch (...) {
throw;
}
In this way destructor of a is always called. However, I don't find it satisfying because an empty catch clause has to be written, and it's not straightforward.
So which of the following should be considered correct, or if there's better practice (especially when implementing a function in a library) ?
Wrap every potentially-throwing function with try-catch block mentioned above;
Pretend the callers to this function always catches the exception;
Because uncaught exception causes crashing, I don't have to destruct local variables.
Put a top-level try-catch(...) in your main function that outputs an error message and exits. This will ensure that unwinding always happens.
Though the question is why you would want that. If you're in any real-world non-embedded environment, the OS will clean up all resources of your process. There's no maybe about it. And since there are other ways for a process to crash which don't involve exceptions, you can't rely on destructors for cleanup in such a case anyway.
If you're in an embedded environment, the situation is similar. You don't have an OS to clean up, maybe, but crashes usually lead to a device reset, which has the same effect. And again, you can't rely on destructors because there are other ways to crash.

What is wrong with this c++ code using destruction?

#include <iostream.h>
class a {
public:
~a() { cout << 1; }
};
int main()
{
a ob;
ob.~a();
return 0;
}
if wrong than what is wrong with it?I've tried this code running on turbo c++,still i'm getting the error of
member identifier expected at "ob.~a();"line
else guess the output?
You don't call destructor functions explicitly usually. They will be called implicitly when the instance goes out of scope.
Calling a destructor function for the same instance twice leads to undefined behavior.
There's no compiler error with a modern compiler to be observed though. See here please. May be that was one of the rare good decisions from the Turbo C++ designers leaving such in an error message.
There are rare cases to call the destructor function explicitly, e.g. if you're maintaining a pool of instances created with placement new.
The call might work with ob.a::~a().
That being said, you don't need and should not call the destructor explicitly, it is called automatically once the ob object goes out of scope.

How to tell the destructor is not called? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I just had an interview question, the interviewer asked
How to tell the destructor is not called when it should have be called?
And what will you do if the destructor is not called?
To be honest, I don't know the answer. My guess is that putting the destructor inside a try catch block, but I have never seen people doing that. Is there a better solution?
There are a number of ways that the destructor of an object can fail to be called:
call abort or _exit (even exit will leave stack variables undestructed).
have the constructor thrown an exception. (Technically, if the constructor threw, the object never started to exist, so there wasn't an object to have its destructor called).
invoke undefined behaviour (at which point the C++ standard allows anything to happen). Calling deleteon an array allocated with new [] is one way of invoking undefined behaviour, and one common behaviour is to call the destructor of the first object only (leaving second and subsequent undestructed) - but it's still undefined behaviour.
Another way to invoke undefined behaviour is a way which is quite likely to leave a destructor uncalled is to have a pointer-to-base which actually points to a derived object, and call delete on the pointer-to-base. If the base class doesn't have a virtual destructor, you have undefined behaviour.
you have not yet called delete on a pointer allocated with new (this is particularly problemmatic if you have a memory leak). (This is actually a particularly common case of "the destructor is not supposed to have been run yet").
If you are trying to debug a program and want to find out if the destructor is being invoked, then
set a break point and run under the debugger
printf or whatever logging framework you are using.
Here is another classic no-destruction:
#include <iostream>
#include <memory>
class Base
{
public:
Base()
{
std::cout << "All your base, sucker!" << std::endl;
}
~Base() <-- note lack of virtual
{
std::cout << "Base destroyed!" << std::endl;
}
};
class Sub: public Base
{
public:
Sub()
{
std::cout << "We all live in a Yellow Submarine..." << std::endl;
}
~Sub()
{
std::cout << "Sub destroyed" << std::endl;
}
};
int main()
{
std::unique_ptr<Base> b(new Sub());
}
Output:
All your base, sucker!
We all live in a Yellow Submarine...
Base destroyed!
Because Base's destructor is not virtual, ~Base is called instead of ~Sub on destruction, and ~Base has no clue that Sub even exists and can't call ~Sub to finish clean-up.
You can for example put a static bool in the class you want to test, set it true in the constructor and false in the destructor. When the destructor is not called, the bool will remain true. Or it can be a static int, increment in the constructor and decrement in the destructor (and check counts before and after the scope). This is one of simple methods to check for resource leaks. I was already using this technique in unit tests to easily check if the correct constructor has been called when a custom smart pointer went out of scope.
The destructor might not be called in many situations, usually as a result of programming error. For example:
deleting inherited class through a base class pointer without having virtual destructor (then only base destructor is called)
deleting pointer to forward declared class (this case is tricky, as only some of the compilers issue a warning)
forgetting to delete at all (memory leak)
initializing object by placement new and not calling the destructor manually (which is required for placement new)
mismatched array/non-array operators (allocating by new[] and deleting by regular delete - if it does not crash it only calls destructor of the first item)
I do not know what Interviewer wanted to ask you as context is not clear but below points may be helpful
For a object on stack - Destructor is called as the object go out of scope.
For a object created on heap - for each object created by new , a delete will call the destructor. In case the program terminates before delete the destructor may not be called, In such proper handling should be done ( I would recommend using smart pointers to avoid such cases)
Here is an example where the destructor is not called:
#include <iostream>
class A {
public:
~A() { std::cout << "Destructor called" << std::endl;}
};
int main()
{
A *a = new A;
return 0;
}
There are plenty of other examples. Like casting, static, ...
It's not easy to detect a "negative event": that something didn't happen.
Instead what we test for is some event which happens unconditionally, and always after the interesting event that we are trying to detect (when that event does happen). When that other even happens, we then know that we are past the point in time when the interesting happen should have happened (if it happened at all). At that point, we have justification in looking for some positive evidence which determines whether the interesting event happened or not.
For instance, we can have the destructor set some kind of flag, or invoke some callback function or whatever. We also know that a C++ program executes statements in sequence. So suppose we don't know whether a given destructor was called during the execution of statement S1 in S1 ; S2. We simply arrange for the gathering of evidence, prior to executing S1, and then in or after S2, we look for that evidence (is the flag set, was the callback invoked, ...)
If this is just during debugging, then use your debugger or code coverage tools!
If you're wondering "is this line of code executed while I run such and such", then put a debugger breakpoint on it..
Or run a code coverage tool and then analyze the results: it will tell you how many times the lines of your program were reached. Lines that weren't executed will be flagged as never reached (no coverage). Code coverage can accumulate the coverage info from multiple runs of the program; they can help you find code that is not being hit by your test cases.

How can I catch exceptions thrown from constructor of a global instance of a class?

I know that having global variables is not appreciated. But in the book, The C++ programming language, by Bjarne Stroustrup, Author says that " The only way to gain control in case of throw from an initializer of a non local static object is set_unexpected() ". How is it done?
I posted the question in some other forums and got some answers.
First one was to declare a pointer rather than having an object and to initialize it in main()
Second one was to derive the class (whose constructor throws the exception ) from another class which performs set_terminate so as to set a meaningful handler. The second one seems to work fine in codeblocks ide.
The code I used to test check it is:
void f() //Unexpected exception handler
{
cout<<"Terminate called "<<endl;
exit (0);
}
class A //Base class that performs set_unexpected
{
terminate_handler h;
public:
A()
{
h=set_terminate(f);
}
~A()
{
set_terminate(h);
}
};
class B:public A //Derived class that throws unexpected_exception
{
public:
B()
{
throw 1;
}
};
B b;
int main()
{
}
The program displays the message: "Terminate called" and exits.
try/catch block are within or along with function scope. Thus global objects cannot reside within try/catch scope, so you can never catch those exceptions.
You can explore the special try/catch syntax:
class Test {
public:
Test ()
try { throw 0; }
catch(...) {}
};
This provides some relief in handling such exceptions. Here is one thread discussing the same.
However, you have to provide such syntax for every class for which you declare global objects
You might be wondering that what's the difference if you put try/catch inside the constructor itself? Well if a global object fails to initialize then the internal try/catch will silently absorb it, which is bad.
But the above syntax will give you a chance for error diagnosis and then again rethrow the exception which will terminate the program.
See this thread for more details.
On the other hand, std::unexpected() is called when there is no appropriate catch() for a thrown exception. This function is standard, but you can configure your own by using std::set_unexpected().
It's very easy to miss the point with error handling in C++, with exceptions, terminate, abort, and so on. The premise that regular code really fears to brake is that destructors will clean up everything constructed so far. So stack unwinding should be the focus, not the means you use for error handling, be it exceptions or something else.
To end the program in a catch in main(), usually you just return an error, or exit(EXIT_FAILURE), so after the stack unwinding you already performed, static duration variables are also destroyed normally.
With global variables that are initialized before main(), that's often all you need. You can preserve destructors functionality simply by using exit instead of throw in their constructors. Other global variables constructed so far are destroyed before the program ends, unlike with throw in a default setup. exit does not unwind the stack, but at this moment there are no destructors to be called by unwinding (except as edited below).
This might be a simpler solution for later readers with the problem in the question title.
EDIT: Besides automatic duration variables, stack unwinding also destroys completed bases and members of a class that throws on construction, which the exit solution does not cover. If you have a global with subobjects that need destruction, you still have to wrap its constructor in a try/catch, or manage its constructor failure manually. The catch in this case needs to call exit for other already constructed globals to be destroyed.

Detecting when a "new" item has been deleted [duplicate]

This question already has answers here:
How can I determine if a C++ object has been deallocated?
(6 answers)
Closed 4 years ago.
Consider this program:
int main()
{
struct test
{
test() { cout << "Hello\n"; }
~test() { cout << "Goodbye\n"; }
void Speak() { cout << "I say!\n"; }
};
test* MyTest = new test;
delete MyTest;
MyTest->Speak();
system("pause");
}
I was expecting a crash, but instead this happened:
Hello
Goodbye
I say!
I'm guessing this is because when memory is marked as deallocated it isn't physically wiped, and since the code references it straight away the object is still to be found there, wholly intact. The more allocations made before calling Speak() the more likely a crash.
Whatever the reason, this is a problem for my actual, threaded code. Given the above, how can I reliably tell if another thread has deleted an object that the current one wants to access?
There is no platform-independent way of detecting this, without having the other thread(s) set the pointer to NULL after they've deleted the object, preferably inside a critical section, or equivalent.
The simple solution is: design your code so that this can't occur. Don't delete objects that might be needed by other threads. Clear up shared resource only once it's safe.
I was expecting a crash, but instead
this happened:
That is because Speak() is not accessing any members of the class. The compiler does not validate pointers for you, so it calls Speak() like any other function call, passing the (deleted) pointer as the hidden 'this' parameter. Since Speak() does not access that parameter for anything, there is no reason for it to crash.
I was expecting a crash, but instead this happened:
Undefined Behaviour means anything can happen.
Given the above, how can I reliably tell if another thread has deleted an object that the current one wants to access?
How about you set the MyTest pointer to zero (or NULL). That will make it clear to other threads that it's no longer valid. (of course if your other threads have their own pointers pointing to the same memory, well, you've designed things wrong. Don't go deleting memory that other threads may use.)
Also, you absolutely can't count on it working the way it has. That was lucky. Some systems will corrupt memory immediately upon deletion.
Despite it's best to improve the design to avoid access to a deleted object, you can add a debug feature to find the location where you access deleted objects.
Make all methods and the destructor virtual.
Check that your compiler creates an object layout where the pointer to
the vtable is in front of the object
Make the pointer to the vtable invalid in the destructor
This dirty trick causes that all functions calls reads the address where the pointer points to and cause a NULL pointer exception on most systems. Catch the exception in the debugger.
If you hesitate to make all methods virtual, you can also create an abstract base class and inherit from this class. This allows you to remove the virtual function with little effort. Only the destructor needs to be virtual inside the class.
example
struct Itest
{
virtual void Speak() = 0;
virtual void Listen() = 0;
};
struct test : public Itest
{
test() { cout << "Hello\n"; }
virtual ~test() {
cout << "Goodbye\n";
// as the last statement!
*(DWORD*)this = 0; // invalidate vtbl pointer
}
void Speak() { cout << "I say!\n"; }
void Listen() { cout << "I heard\n"; }
};
You might use reference counting in this situation. Any code that dereferences the pointer to the allocated object will increment the counter. When it's done, it decrements. At that time, iff the count hits zero, deletion occurs. As long as all users of the object follow the rules, nobody access the deallocated object.
For multithreading purposes I agree with other answer that it's best to follow design principles that don't lead to code 'hoping' for a condition to be true. From your original example, were you going to catch an exception as a way to tell if the object was deallocated? That is kind of relying on a side effect, even if it was a reliable side effect which it's not, which I only like to use as a last resort.
This is not a reliable way to "test" if something has been deleted elsewhere because you are invoking undefined behavior - that is, it may not throw an exception for you to catch.
Instead, use std::shared_ptr or boost::shared_ptr and count references. You can force a shared_ptr to delete it's contents using shared_ptr::reset(). Then you can check if it was deleted later using shared_ptr::use_count() == 0.
You could use some static and runtime analyzer like valgrind to help you see these things, but it has more to do with the structure of your code and how you use the language.
// Lock on MyTest Here.
test* tmp = MyTest;
MyTest = NULL;
delete tmp;
// Unlock MyTest Here.
if (MyTest != NULL)
MyTest->Speak();
One solution, not the most elegant...
Place mutexes around your list of objects; when you delete an object, mark it as null. When you use an object, check for null. Since access is serialized, you'll have a consistent operation.