static unique_ptr calls destructor twice - c++

I use a singleton pattern which returns a reference to unique_ptr dereference. Here is the code,
#include <iostream>
#include <memory>
using std::cout; using std::endl;
using std::unique_ptr;
namespace Settings {
class Lazy {
Lazy() { cout << "Lazy::Lazy() " << this << endl; }
public:
~Lazy() { cout << "Lazy::~Lazy() " << this << endl; }
static Lazy &instance()
{
static unique_ptr<Lazy> lazy(new Lazy);
return *lazy;
}
};
Lazy &lazy()
{ return Lazy::instance(); }
}
int main()
{
cout << "main starts!" << endl;
auto state = Settings::lazy();
cout << "auto state = Settings::lazy() " << &state << endl;
cout << "main ends!" << endl;
return 0;
}
I was expecting that the destructor of the class would call only once but although the constructor called once destructor called twice, here is the output,
main starts!
Lazy::Lazy() 0xb1ec20
auto state = Settings::lazy() 0x7ffe17ae18b8
main ends!
Lazy::~Lazy() 0x7ffe17ae18b8
Lazy::~Lazy() 0xb1ec20
why destructor called twice? And even the second call this address is different.

Because you have 2 instances of the singleton, and both get destroyed.
The reason why you have to 2 singletons, is that when you get the singleton auto state = Settings::lazy(); a copy is created. You might be returning a reference, but state isn't a reference, so a copy is created.
Making state a reference fixes the problem: auto& state = Settings::lazy();

Rakete1111 solution is correct, but you might also want to delete the copy constructor and copy assignment for your singleton. That way you would prevent errors like this from ever happening.

Singleton class must disable any copy/move constructors & assignment/move operators.
Otherwise this is not a singleton.
Thus,
Lazy(Lazy &) = delete;
Lazy(Lazy &&) = delete;
Lazy &operator=(Lazy &) = delete;
Lazy &operator=(Lazy &&) = delete;
Then the following will be the only valid operation:
auto& state = Settings::lazy();

Related

std::map object destructor getting called?

I have a global map object which contains an ID and a class object, but I don't understand why the destructor for the objects in the map are getting called.
#include <map>
#include <iostream>
#include <cassert>
#include <chrono>
#include <thread>
class TestMapObject{
private:
std::string m_sName;
public:
TestMapObject(const std::string& sName){
std::cout << "Constructor called" << std::endl;
m_sName = sName;
}
~TestMapObject(){
std::cout << "Destructor called" << std::endl;
}
const std::string& GetName(){
return m_sName;
}
};
namespace Test{
enum ETestMapKeyId{
k_ETestMapKeyNone = 0,
k_ETestMapKeyFirst,
k_ETestMapKeySecond,
};
std::map<ETestMapKeyId, TestMapObject> g_tMap;
TestMapObject* GetMapObjectById(ETestMapKeyId eID){
auto itFound = g_tMap.find(eID);
assert(itFound != g_tMap.end());
return &itFound->second;
}
}
int main(){
Test::g_tMap.insert(std::pair<Test::ETestMapKeyId,TestMapObject>(Test::k_ETestMapKeyFirst,TestMapObject("Alice")));
Test::g_tMap.insert(std::pair<Test::ETestMapKeyId,TestMapObject>(Test::k_ETestMapKeySecond,TestMapObject("Mocha")));
//destructor gets called here
std::cout << " are we destructed? " << std::endl;
TestMapObject* tmKeyFirst = Test::GetMapObjectById(Test::k_ETestMapKeyFirst);
TestMapObject* tmKeySecond = Test::GetMapObjectById(Test::k_ETestMapKeySecond);
for(;;){
std::this_thread::sleep_for (std::chrono::seconds(1));
std::cout << tmKeyFirst->GetName() << std::endl ;
std::cout << tmKeySecond->GetName() << std::endl ;
}
return 0;
}
I'm able to retrieve a pointer to the objects with GetMapObjectById and continuously able to print their name (Which might be undefined behavior considering their destructor was called). But I'm unsure why the destructor gets called before the application ends..
Output
Constructor called
Destructor called
Destructor called
Constructor called
Destructor called
Destructor called
are we destructed?
---continues loop print
Alice
Mocha
What you see is not the std::map getting destroyed, but the temporaries you are using to insert elements in the map. You can use emplace to avoid the construction (and destruction) of that temporaries:
Test::g_tMap.emplace(Test::k_ETestMapKeyFirst,"Alice");
Test::g_tMap.emplace(Test::k_ETestMapKeySecond,"Mocha");
Live Demo

Constructer Calling order

I know when a constructer is being called, then it gets created in the memory, and when it gets out of the block it gets destroyed unless it's static.
Know I have this code:
#include <iostream>
#include <string>
using namespace std;
class CreateSample
{
private:
int id;
public:
CreateSample(int i)
{
id = i;
cout << "Object " << id << " is created" << endl;
}
~CreateSample()
{
cout << "Object " << id << " is destroyed" << endl;
}
};
void fuct()
{
CreateSample o1(1);
static CreateSample o2(2);
}
CreateSample o3(3);
void fuct2(CreateSample o);
int main()
{
fuct();
static CreateSample o4(4);
CreateSample o5(5);
fuct2(o5);
return 0;
}
void fuct2(CreateSample o)
{
CreateSample o6 = o;
}
and my concern is in object o5, why it's getting called once and gets destroyed 3 times?
When you wrote fuct2(o5); you're calling the function fuct2 and passing the argument by value. This means a copy of the argument will be passed to the function using the implicitly defined copy constructor. Thus you get the 2nd destructor call corresponding this object o.
Moreover, in fuct2 you have CreateSample o6 = o; which will also use the implicitly defined copy constructor to create o6. Thus you will get a third call to the destructor corresponding to this o6.
You can confirm this for yourself by adding a copy ctor as shown below:
class CreateSample
{
//other code here
public:
CreateSample(const CreateSample&obj): id(obj.id)
{
std::cout<<"Copy ctor called"<<std::endl;
}
};
And the output you will get is:
Object 5 is created <------ctor called for o5
Copy ctor called <------copy ctor called for parameter o
Copy ctor called <------copy ctor called for object o6
Object 5 is destroyed <------destructor called for o6
Object 5 is destroyed <------destructor called for o
Object 5 is destroyed <------destructor called for o5
Demo
Though in this particular example you don't strictly require a custom copy constructor or a custom copy assignment operator, they may be needed in other situations. Refer to the rule of three.
CreateSample o5(5); calls the constructor CreateSample(int). fuct2(o5); and CreateSample o6 = o; call the implicitly-defined default copy constructor CreateSample(CreateSample const&). All three of these variables (o6, o, and o5) call the destructor ~CreateSample() when their scope is exited.
The fix is to follow the rule of three and also define a copy constructor and copy-assignment operator:
class CreateSample
{
// ...
CreateSample(CreateSample const& o) {
id = o.id;
cout << "Object " << id << " is copy-constructed" << endl;
}
CreateSample& operator=(CreateSample const& o) {
cout << "Object " << id << " is copy-assigned from " << o.id << endl;
id = o.id;
return *this;
}
}
Demo on Compiler Explorer

copy sematics for callable objects involving "this" pointer

I have a class member which is of type std::function that binds to this pointer by using std::bind.
I implemented assignment operator which must also copy the callable object, however issue is in that, which this should be copied? this this or other this?
Here is sample compileable code to demonstrate:
#include <functional>
#include <iostream>
using func = std::function<void()>;
struct A
{
~A()
{
std::cout << "---destructor: " << this << std::endl;
other_callable();
this_callable();
}
A(const char* name) :
mName(name)
{
other_callable = std::bind(&A::f, this);
this_callable = std::bind(&A::f, this);
}
A& operator=(const A& ref)
{
if (this != &ref)
{
other_callable = ref.other_callable;
this_callable = std::bind(&A::f, this);
mName = ref.mName;
}
return *this;
}
void f()
{
std::cout << mName << ": " << this << std::endl;
}
func other_callable;
func this_callable;
const char* mName;
};
int main()
{
A a("a");
A b("b");
a.other_callable();
b.this_callable();
std::cout << "-------------------" << std::endl;
a = b;
}
Following is non unique sample output:
a: 00000090447FF3E0
b: 00000090447FF490
-------------------
---destructor: 00000090447FF490
b: 00000090447FF490
b: 00000090447FF490
---destructor: 00000090447FF3E0
b: 00000090447FF490
b: 00000090447FF3E0
As you can see non expected callable object is called in second instance.
What is the problem?
Problem is with this pointer that is stored inside the callable object, copying the callable also copies the this pointer which means this is no longer this but rather "other this".
To understand my issue, the callable object is an event callback that is being called from external code which assumes that callable will execute on this instance but it doesnt, it executes on other instance that was copied.
My question is what would be the correct way to implement copy semantics here?
Right now I favor the this_callable version rather than other_callable because it referrs to this this rather than other this.
But I'm not sure whether this is good or bad beyond that it works as expected, while simply copying the callable (other_callable) causes bugs in my code not easy to explain beyond this example.
Is my design with this_callable acceptable or should I use other_callable for copy sematics and change design elsewhere?

Trying to create object using constructor inside static function in C++

I was trying to create an object inside static function using a constructor.
Here is the code
class A {
public:
A() { this->a = 50; std::cout << "constructor called... " << this << std::endl; setAddr(this); }
~A() { this->a = 10; std::cout << "destructor called... " << this << std::endl; }
int a;
static A* addr;
static void setAddr(A* ad) { addr = ad; }
static A &create() { A(); return *addr; }
};
A* A::addr = NULL;
int main() {
A &ptr = A::create();
std::cout << "a = " << ptr.a << std::endl;
ptr.a = 100;
std::cout << "a = " << ptr.a << std::endl;
getch();
return 0;
}
I know using new is best way to do it,but i was trying to do it using contructor to know whether it can be done or not.
The output was:
constructor called... 009AF874
destructor called... 009AF874
a = 10
a = 100
Now here is my question,
1) why destructor is called when did not create an object using any declaration like A obj;
2) and if the destructor is called then how I am able to assign a value to otr.a;
By looking at the program's output I made the following conclusion.
1) I read somewhere that constructor is called after the memory has been allocated to object. And if an object is created then it has to be destroyed and the scope of the obj decided to destroy it now.
2) Since object address has previous values before destroying it and returns call return the address of the variable storing it. When I try to access it, I was able to do so because that memory address still exists.
That's not how you make a singleton. The statement
A();
creates a temporal object of class A that is destroyed (as per standard) at end of statement.
Indeed, memory is allocated before call of constructor. Resulting object can be assigned or passed by reference or value to any function of this statement, but in former case, reference is valid only until end of call expression. Exception is that if it was assigned to reference, its length of life is extended to one
of reference. After life of object ended, any access to memory it used results in UB, provided that it could be used by any other operations.
Any access to object after destructor was called is an UB as well.
Here is an example (this code intentionally contains UB)
#include <iostream>
class A {
public:
A() { this->a = 50; std::cout << "constructor called... " << this << std::endl; }
~A() { this->a = 10; std::cout << "destructor called... " << this << std::endl; }
int a;
static const A &create() {
const A& addr = A();
std::cout << "a = " << addr.a << std::endl;
return addr;
}
};
int main() {
const A &ref = A::create();
std::cout << "a = " << ref.a << std::endl;
return 0;
}
Note, that C++ allows to bind temporary only to const reference. There are way to work around that, but that's irrelevant.
Output of this program may vary, depending on compiler and level of optimization. E.g. clang with no optimization:
constructor called... 0x7ffc1f7991d0
a = 50
destructor called... 0x7ffc1f7991d0
a = 4202884
gcc may output 10 in last line. MS may crash on it. Keyword is "may", there is no rule that governs what would happen. Object stopped existing after create() returned reference to it because lifespan of addr came to end, and we are left with dangling reference.
Obviously we can extend lifespan of addr by making it static.
static const A &create() {
static const A& addr = A();
std::cout << "a = " << addr.a << std::endl;
return addr;
}
Static variable in function's scope will be created at first call of function and stops to exist when process stops.
constructor called... 0x6031b8
a = 50
a = 50
destructor called... 0x6031b8

Strange object assignment behaviour c++

I have a strange behavior with object assignments. I will much appreciate, if you can explain why this assignment works like this. It has cost me already a lot of time.
I am using Visual Studio Enterprise 2017 (all default settings).
Code:
#include "stdafx.h"
#include <iostream>
using namespace std;
class Test
{
public:
Test()
{
cout << "Constructor of " << this << endl;
}
~Test()
{
cout << "Destructor of " << this << endl;
}
};
int main()
{
cout << "Assignment 1" << endl;
auto t = Test();
cout << "Assignment 2" << endl;
t = Test();
int i = 0;
cin >> i;
return 0;
}
Output (up to cin):
Assignment 1
Constructor of 006FFC9F
Assignment 2
Constructor of 006FFBC7
Destructor of 006FFBC7
Expected Output (up to cin):
Assignment 1
Constructor of 006FFC9F
Assignment 2
Destructor of 006FFC9F
Constructor of 006FFBC7
I wanted to write a test function which creates an object of my (template) class, do some tests, then create a new object and do some more testing. The problem is that t holds the already destructed object after the second assignment.
I know that I can just use dynamic allocation which results in the expected behavior, but why does this program behave different?
Thank you very much.
Regards.
PS: Results are the same, independent of Release/Debug or 64/32 bit compilation
EDIT: More verbose example:
#include "stdafx.h"
#include <iostream>
using namespace std;
class Test
{
private:
float* val;
public:
Test()
{
val = new float;
cout << "Constructor of " << this << ", addr. of val: " << val << endl;
}
~Test()
{
cout << "Destructor of " << this << ", addr. of val: " << val << " --> DELETING VAL!" << endl;
delete val;
}
float* getVal() { return this->val; }
};
int main()
{
cout << "Assignment 1" << endl;
auto t = Test();
cout << "Assignment 2" << endl;
t = Test();
cout << "Val Address: " << t.getVal() << endl;
int i = 0;
cin >> i;
return 0;
}
Output (it holds a deleted pointer at the end!!!):
Assignment 1
Constructor of 004FFBDC, addr. of val: 0072AEB0
Assignment 2
Constructor of 004FFB04, addr. of val: 00723928
Destructor of 004FFB04, addr. of val: 00723928 --> DELETING VAL!
Val Address: 00723928
With
auto t = Test();
you actually construct two objects. First is the Test() which constructs a temporary object. The second is the construction of t which is made through copy-construction. There is no assignment being made here, even if the = operator is used, it's copy-construction.
If you add a copy-constructor to the Test class similar to your constructor and destructor, you should see it clearly.
As for
t = Test();
here a temporary object is created with Test(). That temporary object is then passed to the (compiler-generated) assignment operator of the Test class, and then the temporary object is promptly destructed.
The object t itself is not destructed, it should not be as it is the destination of the assignment.
Your confusion seems to be a mistaken expectation that the original object is destroyed when assignment takes place. Like, in this code:
cout << "Assignment 2" << endl;
t = Test();
This piece of code invokes the move-assign operator. Since you didn't define one, the default one generated by the compiler is more-or-less going to look like this:
Test & operator=(Test &&) {}
Note how there's no invocation of a constructor or (critically) a destructor in that code. The only Constructors and Destructors that are going to run are on the temporary object (which is what you observe in the actual output). The original object doesn't get destroyed until the code goes out of scope; and why would it? It's not like you can stop using the stack space before then.
Edit: Something which might help you understand what's going on:
#include<iostream>
struct Test {
Test() {std::cout << "Constructed.\n";}
~Test() {std::cout << "Destructed.\n";}
Test(Test const&) {std::cout << "Copy-Constructed.\n";}
Test(Test &&) {std::cout << "Move-Constructed.\n";}
Test & operator=(Test const&) {std::cout << "Copy-Assigned.\n"; return *this;}
Test & operator=(Test &&) {std::cout << "Move-Assigned.\n"; return *this;}
};
int main() {
std::cout << "Test t;\n";
Test t; //Construction
std::cout << "Test t2(t);\n";
Test t2(t); //Copy-Construct
std::cout << "Test t3(std::move(t2));\n";
Test t3(std::move(t2)); //Move-Construct
std::cout << "Test t4 = t;\n";
Test t4 = t; //Copy Construct, due to Copy Ellision
std::cout << "Test t5 = Test();\n";
Test t5 = Test(); //Will probably be a normal Construct, due to Copy Ellision
std::cout << "t = t2;\n";
t = t2; //Copy Assign
std::cout << "t = Test();\n";
t = Test(); //Move Assign, will invoke Constructor and Destructor on temporary
std::cout << "Done! Cleanup will now happen!\n";
return 0;
}
Results as seen when compiled here:
Test t;
Constructed.
Test t2(t);
Copy-Constructed.
Test t3(std::move(t2));
Move-Constructed.
Test t4 = t;
Copy-Constructed.
Test t5 = Test();
Constructed.
t = t2;
Copy-Assigned.
t = Test();
Constructed.
Move-Assigned.
Destructed.
Done! Cleanup will now happen!
Destructed.
Destructed.
Destructed.
Destructed.
Destructed.
DOUBLE EDIT COMBO!:
As I mentioned in comments, val is just a pointer. 8 bytes (on a 64-bit machine) allocated as part of Test's storage. If you're trying to make sure that Test always contains a valid value for val that hasn't been deleted, you need to implement the Rule of Five (previously known as the Rule of Three):
class Test {
float * val;
public:
Test() {val = new float;}
~Test() {delete val;
Test(Test const& t) {
val = new float(*(t.val));
}
Test(Test && t) {std::swap(val, t.val);}
Test & operator=(Test const& t) {
float * temp = new float(*(t.val)); //Gives Strong Exception Guarantee
delete val;
val = temp;
return *this;
}
Test & operator=(Test && t) {std::swap(val, t.val); return *this;};
float & get_val() const {return *val;} //Return by reference, not by pointer, to
//prevent accidental deletion.
};