I ran the following code
#include <iostream>
using namespace std;
class Count
{
private:
int count;
public:
//Constructor
Count():count(0) { cout << "Constructor called" << endl; }
//Destructor
~Count() { cout << "Destructor called" << endl; }
//Display the value.
Count display()
{
cout << "The value of count is " << count << endl;
return *this;
}
};
int main()
{
Count C;
C.display();
}
Result :-
Constructor called
The value of count is 0
Destructor called
Destructor called
In the above case, the destructor is called twice, one for destruction of the "this" object and one for return from main.
Is my observation correct ??
Can anyone explain me also the temporary object created in this process like why it is created, if created??
You are returning a copy from display() method thus it needs to be destructed too. So, in your main you actually have 2 objects, one - implicitly.
The destructor is called twice because your display function returns a copy of the Count instance that it is called on. So that gets destroyed along with your C instance within main.
2 instances = 2 destructor calls.
If you specify and implement your function to return an instance of Count then it will do so. If you don't want this behaviour, then change the return type to void and don't return anything - then your code will contain just the one instance C.
Your code here
Count display() {
// ^^^^^
cout << "The value of count is " << count << endl;
return *this; // <<<<<<
}
creates an implicit copy of your instance that is returned and immediately destroyed, hence the second destructor call.
Yes correct.
Your function display() created a copy which made a second object.
if you return a reference you wouldn't get the copy.
Count& display() { return *this; }
Related
#include <iostream>
#include <vector>
#include <algorithm>
class my {
public:
my() {
counter++;
std::cout << "class constructor" << counter << " \n";}
~my() {
std::cout << "class destructor" << counter << " \n";
counter--;
}
static inline int counter = 0;
};
int main()
{
my v1;
std::vector<my> my_vec;
my * p = new my();
my_vec.push_back(std::move(*p));
my_vec.push_back(std::move(v1));
}
simply example, however I do not understand what I am doing wrong, in result I get 2 extra destructor called than I expect (expect 2). Could some one explain it?
results:
class constructor1
class constructor2
class destructor2
class destructor1
class destructor0
class destructor-1
Analyzing the program step-by-step:
my v1;
One Instance is created, constructor is called.
my * p = new my();
Another instance is created, constructor is called.
my_vec.push_back(std::move(*p));
A copy of the second instance is inserted into the vector; the implicitly defined move-constructor is called (which just copies; no output is printed).
my_vec.push_back(std::move(v1));
The vector allocates new storage for 2 instances, copies the previously stored instance into the new storage (invoking the implicitly defined move-constructor, which just does copying, still no output for this), and invokes the destructor for the instance in the old storage (so first destructor output is printed).
Then, the vector goes out of scope, so its two contained elements get destroyed (so, 2 destructor calls). Then, v1 goes out of scope, printing the 4th destructor call. The instance p is leaked, i.e. never destroyed (memory leak).
Please see inline ...
#include <iostream>
#include <vector>
class my {
public:
my() {
counter++;
std::cout << "class constructor" << counter << " \n";
std::cout << "Object Address : " << this << std::endl;
}
~my() {
std::cout << "class destructor" << counter << " \n";
std::cout << "Object Address : " << this << std::endl;
counter--;
}
static inline int counter = 0;
};
int main()
{
my v1; /* 1. Object on stack (constructor called) */
std::vector<my> my_vec;
my * p = new my(); /* 2. Object created on heap (constructor called) */
my_vec.push_back(std::move(*p));
my_vec.push_back(std::move(v1));
}
Output is:
class constructor 1 Address : 0x7ffee1488760
class constructor 2 Address : 0x7f9f47400350
class destructor 2 Address : 0x7f9f474026e0
class destructor 1 Address : 0x7f9f474026f1
class destructor 0 Address : 0x7f9f474026f0
class destructor -1 Address : 0x7ffee1488760
Object on the stack called destructor as soon as it goes out of the scope i.e. Scope of the object on stack is limited to the code block. In this case block end when main exits.
But the object on heap (new) is a potential leak, had this being inside while loop would have consumed memory and eventually crashed. For each new you need to explicitly called delete, which means you have to call its destructor. Thanks to stack it does that for us but not heap, and c++ also doesn't have garbage collector.
std::move is a copy operation and hence no constructor is called. details here.
Take a look at this code:
#include <iostream>
using namespace std;
class A {
private:
int _x;
int _id;
static int count;
public:
A(int x) : _x(x) {
this->_id = A::count++;
cout << "Object with id " << this->_id
<< " has been created." << endl;
}
~A() {
cout << "Object with id " << this->_id
<< " has been destroyed." << endl;
}
int get_x(void) {
return this->_x;
}
A add(A& object) {
A tmp(this->_x + object._x);
return tmp;
}
};
int A::count = 1;
int main(void) {
A object_1(13);
A object_2(5);
A object_3(12);
object_3 = object_1.add(object_2);
cout << object_3.get_x() << endl;
return 0;
}
Here's the output from the program:
Object with id 1 has been created.
Object with id 2 has been created.
Object with id 3 has been created.
Object with id 4 has been created.
Object with id 4 has been destroyed.
18
Object with id 4 has been destroyed.
Object with id 2 has been destroyed.
Object with id 1 has been destroyed.
I don't understand what happened to Object with id 3? It definitely was created, but I see no line telling me that it was ever destroyed. Can you please tell me what's going on here?
As an aside question, why is it that when I use return 0, the destructors work fine, but when I use exit(EXIT_SUCCESS) I don't see Object with # has been destroyed printed on the screen as though the destructors are never called.
Is the previous object destroyed when the variable holding it gets assigned a new one using a copy constructor?
This question is moot because it is not possible to do so.
When you run
object_a = object_b;
this calls the assignment operator (not the copy constructor). It does not create or destroy any objects (unless your assignment operator does that).
In this case you haven't defined an assignment operator, so the default one is used, which overwrites object_3's ID with the other object's ID (which is 4). So when object_3 is destroyed it prints "Object with id 4 has been destroyed".
I am trying to assign a variable to a return value but the deconstructor is called before the values are assigned to pq. I also get the following error which I'm assuming is an attempt to double delete a variable:
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
PriorityQueue pq;
pq = FindThroughPaths(a, b);
FindThroughPaths(a, b) returns a PriorityQueue.
I may be getting this error because the return value has dynamically allocated member variables.
I am simply trying to find a way to keep the return value of FindThroughPaths(a, b) within the scope and I do not want to create multiple instances just to access it's members. This is an example of what I would like:
PriorityQueue pq;
pq = FindThroughPaths(a, b);
while (!pq.IsEmpty) {
Path tmp = pq.Dequeue();
std::cout << "\n" << tmp.name << " #" << tmp.number;
}
The constructor, deconstructor, and assignment operator for PriorityQueue:
PriorityQueue::PriorityQueue()
{
std::cout << "\nConstructor called." << endl;
items.elements = new ItemType[maxItems];
length = 0;
}
PriorityQueue::~PriorityQueue()
{
std::cout << "\nDeconstructor called." << endl;
delete[] items.elements;
}
PriorityQueue PriorityQueue::operator=(const PriorityQueue &originalPQ)
{
//This function is started after the return value, the right operand, has been deconstructed.
std::cout << "\nAssignment called." << endl;
for (int i = 0; i < maxItems; i++)
items.elements[i] = originalPQ.items.elements[i];
return *this;
}
It is a little hard to tell exactly what the problem is without looking at how you are returning the PriorityQueue from your FindThroughPaths method, but it is likely that the problem is that you are missing a copy constructor in the PriorityQueue class.
PriorityQueue::PriorityQueue(const PriorityQueue &other)
{
std::cout << "\nCopy constructor was called" << endl;
// there are better ways to implement this, but I think this will correctly
// defer to the assignment operator you wrote
*this = other;
}
When you return an object from a method, the copy constructor is invoked to build the object that will be returned. If you have not implemented a copy constructor, then a default implementation is used, and that default will not be sufficient in your case.
The destructor will still be called to destroy the PriorityQueue object that is local to the FindThroughPaths method.
You might find this other question about returning an object from a method to be helpful.
I have a few lines of code and I don't get, why and where the copy constructor is called. Could you explain it to me?
The output is:
CS10
CS99
CC100
Obj10=Obj100
D100
Obj10=Obj99
D99
D10
This is my source code:
#include <iostream>
using namespace std;
class my
{
int m;
public:
my(int i): m(i)
{
cout << "CS" << m << endl;
}
my(const my& c): m(c.m+1)
{
cout << "CC" << m << endl;
}
~my()
{
cout << "D" << m << endl;
}
my& operator=(const my &c)
{
cout << "Obj" << m << "=Obj" << c.m << endl;
return *this;
}
};
my f(my* x)
{
return *x;
}
int main()
{
my m1(10);
my m2(99);
m1 = f(&m2); // creates a new object
m1 = m2; // does not create a new object
}
Why and where is copy constructor called causing the output CC100 and D100?
In this function
my f(my* x)
{
return *x;
}
called in statement
m1 = f(&m2); // creates a new object
the copy constructor is called to copy object *x in the return temporary object.
In fact it looks as
my tmp = *x; // the copy constructor is called
m1 = tmp;
When trying to think about when a copy constructor is called you should keep a few things in mind:
Scope - functions can't see outside of themselves and their associated namespace. If you want to pass a variable to a function you need to save it in the global environment, repush a scoped copy and then operate on it.
When you use passing by reference you operate on the global copy but since in this case you are returning the value that is pointed to and not a pointer you have to push that return value onto the stack separately because it is stored at a different temporary register address that is popped off the stack after you assign it to a permanent location in main. That's where the destructor comes in.
You made a temporary return value to pass the value out of your function so it's got to be deleted because L1, L2, and L3 cache are all prime real estate.
I highly recommend doing a little bit of reading on assembly code operations or even try compiling simple programs into assembly and seeing how the low level languages work under the hood. Cheers!
In this example, why is it ok to return a stack variable? When t() returns, why is it not returning garbage, since the stack pointer has been incremented?
#include << string >>
#include << vector >>
#include << iostream >>
using namespace std;
class X{
public:
X() { cout << "constructor" << endl; }
~X() { cout << "destructor" << endl; }
};
vector <X> t()
{
cout << "t() start" << endl;
vector<X> my_x;
int i = 0;
printf("t: %x %x %x\n", t, &my_x, &i);
my\_x.push\_back(X()); my\_x.push\_back(X()); my\_x.push\_back(X());
cout << "t() done" << endl;
return my_x;
}
int main()
{
cout << "main start" << endl;
vector <X> g = t();
printf("main: %x\n", &g);
return 0;
}
output:
./a.out
main start
t() start
t: 8048984 bfeb66d0 bfeb667c
constructor
destructor
constructor
destructor
destructor
constructor
destructor
destructor
destructor
t() done
main: bfeb66d0
destructor
destructor
destructor
Basically when you return the stack variable my_x you would be calling the copy constructor to create a new copy of the variable. This is not true, in this case, thanks to the all mighty compiler.
The compiler uses a trick known as return by value optimization by making the variable my_x really being constructed in the place of memory assigned for g on the main method. This is why you see the same address bfeb66d0 being printed. This avoids memory allocation and copy construction.
Sometimes this is not at all possible due to the complexity of the code and then the compiler resets to the default behavior, creating a copy of the object.
Because parameters are passed by value. A copy is made. So what is being returned is not the value on the stack, but a copy of it.
Well a copy is returned, the only construct you can not return a copy of it is a static array. So you can not say this...
int[] retArray()
{
int arr[101];
return arr;
}
The compiler is optimized to handle returning "stack variables" without calling the copy constructor. The only thing you need to know about is that that memory allocation is in scope of both the function that allocated it on the stack and the function that the object is returned to.
It does NOT call the copy constructor nor does it allocate it twice.
There may be some special cases and of course it depends on the compiler -- for example, primitives may be copied -- but in general, objects allocated on the stack, don't get copied when being returned.
Example:
struct Test {
};
Test getTest() {
Test t;
std::cout << &t << std::endl; // 0xbfeea75f
return t;
}
int main(int argc, char *argv[])
{
Test t = getTest();
std::cout << &t << std::endl; // also 0xbfeea75f
}