Destructor not called for local objects when we use atexit() - c++

Please help:
I am aware about destructors and atexit() and know following too:
atexit() register a function to be called when the program terminates (e.g. when main() calls a return or when exit() is explicitly called somewhere).
When exit() is invoked, static objects are destroyed (destructor is called), but not objects in local variable scope and of course dynamically allocated objects neither (those are only destroyed if you explicitly call delete).
below code give output as:
atexit handler
Static dtor
Can you please help me knowing why destructor of local objects wont be called when we use atexit()?.
Thanks in advance:
class Static {
public:
~Static()
{
std::cout << "Static dtor\n";
}
};
class Sample {
public:
~Sample()
{
std::cout << "Sample dtor\n";
}
};
class Local {
public:
~Local()
{
std::cout << "Local dtor\n";
}
};
Static static_variable; // dtor of this object *will* be called
void atexit_handler()
{
std::cout << "atexit handler\n";
}
int main()
{
Local local_variable;
const int result = std::atexit(atexit_handler);
Sample static_variable; // dtor of this object *will not* be called
std::exit(EXIT_SUCCESS);//succesful exit
return 0;
}

Calling destructors is not about atexitbut exit.
I don't generally regard std::exit any good C++ programming. In fact, this and the std::atexit
extern "C" int atexit( void (*func)() ); // in <cstdlib>
come from the C standard library. As looking at your example, I believe you have seen http://en.cppreference.com/w/cpp/utility/program/exit, and you have also seen
"Stack is not unwound: destructors of variables with automatic storage durations are not called."
Which is the answer to your question "why"? There are some cases, particularly unrecovered errors you might make use of exit, but generally use should stick to using exceptions, e.g.,
Static static_variable;
int mainactual()
{
Local local_variable;
Sample static_variable;
throw std::exception("EXIT_FAILURE"); // MS specific
// ... more code
}
int main()
{
try
{
mainactual()
}catch ( std::exception & e )
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

Related

Why does explicitly calling a destructor cause double freeing?

The code below ends up with free(): double free detected in tcache 2. I want to know the inner process the error happens through.
#include <string>
class test
{
private:
std::string member;
public:
test(const std::string & arg) { member = arg; };
};
int main()
{
test T = test("test test test test");
T.~test();
return 0;
}
The error depends on the length of the given string; if you change "test test test test" to "test", the program runs fine, at least with g++ on my computer.
std::string has an internal buffer for short strings to avoid memory allocations. If the string is short, then there is no memory to free and it works. If the string is long it tries to free the buffer each time you call the destructor.
Here is more information on the Short String Optimization:
Meaning of acronym SSO in the context of std::string
In your code test T is a local variable and local variables are deleted when they go out of scope.
If you call T.~test() explicitly then it deletes the variable before it goes out of scope. But when the variable really goes out of scope, the destructor is called again.
Consider the example (taken from your code):
#include <string>
#include <iostream>
class test
{
private:
std::string member;
public:
test(const std::string & arg) { member = arg; };
~test()
{
std::cout << " calling destructor "<<std::endl;
}
};
int main()
{
test T = test("test test test test");
//take the call away and you will still have the destructor call
//T.~test();
return 0;
}
If now, you call the destructor explicitly, then you get the destructor called twice (once explicitly and once when the variable goes out of scope)
#include <string>
#include <iostream>
class test
{
private:
std::string member;
public:
test(const std::string & arg) { member = arg; };
~test()
{
std::cout << " calling destructor "<<std::endl;
}
};
int main()
{
test T = test("test test test test");
//causing a double call to the destructor
T.~test();
return 0;
}
The execution would be
calling destructor
calling destructor
free(): double free detected in tcache 2
Abandon
If instead, you have allocated a pointer on test with new, you then need to explicitly call the destructor otherwise, you will have memory leaks.
When excuting the code below, you see that the destructor does not get called even if your pointer goes out of scope.
int main()
{
test* T = new test("test test test test");
// in this case you will have no more destructor automatically
//T.~test();
return 0;
}
You need to deallocate the allocated memory explicitly by calling the destructor but not by using T.~test() because now T is not of type test but test*. You only need to call delete T like this:
int main()
{
test* T = new test("test test test test");
//You need to deallocate the allocated memory explicitly
//T.~test();
delete T;
return 0;
}
And the destructor is called on the allocated memory
Your program has undefined behaviour. That does not mean it has to error, the shorter string behaving differently is allowed.
The destructor is called a second time, when the lifetime of test ends at the } of main.
There are very few situations where calling the destructor of an object is appropriate.

Crash when using a global object, but not when using a local object

I am trying to use libconfig to create a configuration file for my program. There are two scenarios, one which works perfectly (local scope object) and the other which fails (global scope object). I am trying to understand why one fails while the other succeeds, as it is my understanding that both are definitions which create the same object (just in different scope).
1st (does not work): I define a Config object in the global scope. Then I call readFile on the Config object. The program crashes here.
#include <libconfig.h++>
libconfig::Config cfg;
int __attribute__((constructor)) Init()
{
cfg.readFile("/home/jalius/csgo-internal/hack.cfg");
}
2nd (works): I define a local Config object and call readFile on it.
#include <libconfig.h++>
int __attribute__((constructor)) Init()
{
libconfig::Config cfg;
cfg.readFile("/home/jalius/csgo-internal/hack.cfg");
}
When you are calling int __attribute__((constructor)) Init() function at that time the cfg object is not created in your case. Because the order of calling functions decorated with attribute constructor and C++ objects with static storage duration is unspecified. Since object doesn't exists so you are getting segmentation fault error i.e. SIGSEGV signal.
Following is an extract from GCC website:
at present, the order in which constructors for C++ objects with static storage duration and functions decorated with attribute constructor are invoked is unspecified. In mixed declarations, attribute init_priority can be used to impose a specific ordering.
See constructor section on this page for more information.
There is no guarantee that your function int __attribute__((constructor)) Init() will be called before the Config object is constructed.
When you try to read from it, you might actually try to access an unconstructed object. This will cause undefined behavior.
When you create it locally, there is a guarantee that your object will be initialized fully before you use it.
Experiment:
#include <iostream>
enum {
OBJECT_CONSTRUCTOR,
FUNCTION_CONSTRUCTOR,
};
int order[10], cur = 0;
class TestClass {
public:
TestClass() { order[cur++] = OBJECT_CONSTRUCTOR; }
~TestClass() { }
};
TestClass abc;
int __attribute__((constructor)) Init() {
order[cur++] = FUNCTION_CONSTRUCTOR;
}
int main ()
{
std::cout << "Order of execution:\n";
for(int i = 0; i < cur; i++)
{
switch(order[i])
{
case OBJECT_CONSTRUCTOR:
std::cout<<"Object Constructor\n";
break;
case FUNCTION_CONSTRUCTOR:
std::cout<<"Function Constructor\n";
break;
}
}
return 0;
}
Results:
Order of execution:
Function Constructor
Object Constructor

Using smart_ptr for user defined class objects

As a C++ neophyte trying to understand smart pointers. I have written below code to check.
It did compile and run but I was expecting the destructor of my class to be invoked and print the cout's from the destructor but it didn't .
Do we need to overload any function in the user defined class so that its destructor is called when the smart_ptr object of that class gets destroyed.
Why is that it did not invoke the object destructor. What is that i am missing?
#include <iostream>
#include <cstdlib>
#include <tr1/memory>
#include <string>
//using namespace std;
class myclass
{
public:
myclass();
myclass(int);
~myclass();
private:
int *ptr;
std::string *cptr;
};
myclass::myclass()
{
std::cout << "Inside default constructor\n";
}
myclass::myclass(int a)
{
std::cout << "Inside user defined constructor\n" ;
ptr = new int[10];
cptr = new std::string("AD");
}
myclass::~myclass()
{
std::cout << "Inside destructor..\n";
delete [] ptr;
delete cptr;
std::cout << "Freed memory..\n";
}
int main()
{
int i;
std::cin >> i;
std::tr1::shared_ptr<std::string> smartstr(new std::string);
std::tr1::shared_ptr<myclass> smart_a(new myclass(i));
if(i == 0)
{
std::cout << "Exiting...\n";
exit(-1);
}
}
The reason the object is never destroyed is because you are exiting the program by calling exit. This causes the program to exit before the smart pointer objects have a chance to go out of scope thus the objects they manage are never destroyed. Since you are in main use a return statement instead of calling exit.
And, as additional information to other answers, note from the Standard:
Per ยง3.6.1/4:
Terminating the program without leaving the current block (e.g., by
calling the function std::exit(int) (18.5)) does not destroy any
objects with automatic storage duration (12.4).
In the code below,
if(i == 0)
{
std::cout << "Exiting...\n";
exit(-1);
}
You are terminating the program by calling exit(), so the object is never destroyed. So remove the exit(-1); from the code.
One possible solution is ensure that your buffer is flushed in your destructor. Use std::endl; in your destructor. For more information, please look here: Buffer Flushing, Stack Overflow

C++ global function

I declared a global function in a .cpp file void functionA(). I would like functionA() to be called exactly once before the start-up ( not inside main()). The thing I realize is if the function is int functionB(), I could call it using static int A = functionB(). But for return value of void, how could I do that?
Thanks
You put it into the constructor of a global object:
void functionA();
namespace {
struct global_initializer {
global_initializer() {functionA();}
} the_global_initializer;
}
Note that this has the common drawbacks of global initialization: While globals within the same translation unit are initialized in the order of their definition, the order of initialization of globals across translation units is undefined.
Also, linkers might choose to eliminate unreferenced objects (the_global_initializer), which would prevent functionA() from being called.
static int a = functionA(), 42;
There are few places where comma expressions are useful, but this may be one of them.
You could use a static struct, it's constructor will get called before main.
#include <iostream>
void functionA(void)
{
std::cout << "Hello, ";
}
static struct BeforeMain
{
BeforeMain(void)
{
// stuff in this constructor is executed before "main" function
functionA();
}
} g_beforeMain; // shouldn't get used though
int main(void)
{
std::cout << "world!" << std::endl;
return 0;
}
This will print Hello, world!, although I'm new to C++, so this may not be the best approach.
Solution 1: Make that void function to have a return type (say int) and return a dummy return value
If you can't do Solution 1,
Solution 2: Write a wrapper function as shown. Make sure to write code so that wrapper can be called only once (unless it is fine to do so multiple times)
Wrap it up! (and document extensively).
void fA(){}
int wrapper(){
// Have checks here to ensure it is not called more than once
fA();
return 0;
}
// Extensively document such as `'x' is a bogus dummy variable.`
static int x = wrapper();
int main(){
}

Exceptions - c++

I'm trying to understand the behavior of exceptions in c++.
I wrote the following code:
class A{
public:
A(){
};
~A(){
cout<<"hello";
};
};
int exceptionTest(){
throw "blablabla";
};
int main(){
A sd;
int test = exceptionTest();
return 0;
}
I've noticed that in this case the distructor gets called even though no one caught the exception.
If I change the "main" code to:
int main(){
A* sd = new A();
int test = exceptionTest();
return 0;
}
The distructor will not be called.
Can anyone please tell me what is the reason for the different behavior?
Thanks,
Li
The fact that you are throwing an exception is irrelevant here. In your first example, sd is an object that exists on the stack. When execution exits its scope, for whatever reason, it gets destroyed. In the second example, sd is a pointer to an object that was explicitly allocated using new. This object will not be destroyed until that pointer is passed to delete; since you never do so, your program is currently leaking it.
The standard has the following to say on the matter:
-9- If no matching handler is found in a program, the function terminate() is called; whether or not the stack is unwound before this call to terminate() is implementation-defined.
So your compiler performs stack unwinding (invoking destructors of locals), others may not. For example, with G++ or codepad.org, this program will not output "hello".
Dynamically allocated objects are not destroyed until you explicitly destroy them (with delete or such). In particular, if an exception occurs in the meantime, code may never reach the deallocation statement.
Local variable destructors are called automatically, as soon as the variable is out of scope.
Destructors are never called on pointers, so you must call it yourself.
I've noticed that in this case the distructor gets called even though no one caught the exception.
That's exactly what to expect.
This mechanism is a RAII consequence that makes you "sure" that resources will be freed even if there is an exception. For example :
class File
{
public:
File( const std::string filename ) : file_handler(file_open( filename )) { } // whatever the implementation
~File() { file_close(file_handler); }
private:
FileHandler file_handler;
};
void test(){ throw "This is a test"; }
int main()
{
File file("test.txt");
test();
return false;
}
You're assured that the file will be closed even with the throw. So if you use RAII to manage your resources.
That's because when the exception is thrown, until it get catch, it goes back in the call stack and if there is no catch the local objects are destroyed the way they would be if we got out of scope.
This is not really an answer, but I might clarify the behavior, in case of RAII mechanism, that I understood from the other answer and Mike's comments.
#include <iostream>
class Bar
{
public:
Bar() { std::cout << "Bar constructor" << std::endl; }
~Bar() { std::cout << "Bar destructor" << std::endl; }
};
void foo()
{
throw("Exception");
}
int main()
{
// Variation, add { to create a new scope
Bar bar;
foo();
// Variation : }
return 0;
}
Using g++, this code, where the exception is not catched will output the following:
Bar constructor
terminate called after throwing an instance of 'char const*'
Aborted
Meaning that g++ does not unwind the stack (or let go the variable out of scope, if I understand the "variant" correctly), so the destructor is not called.
However, if you catch the exception:
#include <iostream>
class Bar
{
public:
Bar() { std::cout << "Bar constructor" << std::endl; }
~Bar() { std::cout << "Bar destructor" << std::endl; }
};
void foo()
{
throw("Exception");
}
int main()
{
try
{
Bar bar;
foo();
}
catch (...)
{
// Nothing here
}
return 0;
}
then the output will be
Bar constructor
Bar destructor
and you recover the correct behavior.