An exercise that Stroustrup wants the reader to do is understand the output of the following program.

#include "../../std_lib_facilities.h"

struct X {
	int val;

	void out(const string& s, int nv) {
	   cerr << this << "->" << s << ":" << val << "(" << nv << ")\n";
	}

	X() {
	   out("X()", 0);
	   val = 0;
	}

	X(int v) {
	   out("X(int)", v);
	   val = v;
	}

	X(const X& x) {
	   out("X(X&)", x.val);
	   val = x.val;
	}

	X& operator = (const X&a) {
	   out("X::operator = ()", a.val);
	   val = a.val;
	   return *this;
	}

	~X() {
	   out("~X()", 0);
	}
};

X glob(2);
X copy(X a) {return a;}
X copy2(X a) {
   X aa = a;
   return aa;
}

X& ref_to(X& a) {return a;}

X* make(int i) {
   X a(i);
   return new X(a);
}

struct XX {
   X a;
   X b;
};

int main ()
{
   X loc(4);
   X loc2 = loc;
   loc = X(5);
   loc2 = copy(loc);
   loc2 = copy2(loc);

   X loc3(6);
   X& r = ref_to(loc);
   delete make(7);
   delete make(8);
   vector<X> v(4);

   XX loc4;
   X* p = new X(9);
   delete p;

   X* pp = new X[5];
   delete[] pp;

   keep_window_open();
   return 0;
}

I don't understand this program. It is supposed to have different types of constructors and destructors, variables created and variables destroyed. It prints out whenever a variable is created or destroyed. I don't understand the output. It is a series of memory addresses with an X or an ~X after it. I understand the allocation of memory and the freeing of memory. I assume the net use of memory is zero, representing no memory leak. I can't follow what is going on. I can't cut and paste the output because it is in the console window, but here is a bit of it.

004241A0->X(int):0(2)
0012FF54->X(int):-858993460(4)
0012FF48->X(X&):-858993460(4)
0012FF54->X::operator = ():5(4)
0012FD30->X(X&):969884377(5)
0012FD30->~X():(5)

What does all this mean? Are there tutorials that explain this? Stroustrup has sort of thrown us in the water and left us on our own to find a way to swim.

I managed to copy and paste the the entire output below.

004241A0->X(int):0(2)
0012FF54->X(int):-858993460(4)
0012FF48->X(X&):-858993460(4)
0012FD54->X(int):-858993460(5)
0012FF54->X::operator = ():4(5)
0012FD54->~X():5(0)
0012FD30->X(X&):702684171(5)
0012FD6C->X(X&):-858993460(5)
0012FD30->~X():5(0)
0012FF48->X::operator = ():4(5)
0012FD6C->~X():5(0)
0012FD30->X(X&):702684171(5)
0012FD10->X(X&):-858993460(5)
0012FD84->X(X&):-858993460(5)
0012FD10->~X():5(0)
0012FD30->~X():5(0)
0012FF48->X::operator = ():5(5)
0012FD84->~X():5(0)
0012FF3C->X(int):-858993460(6)
0012FD14->X(int):-858993460(7)
00345A48->X(X&):-842150451(7)
0012FD14->~X():7(0)
00345A48->~X():7(0)
0012FD14->X(int):-858993460(8)
00345A48->X(X&):-842150451(8)
0012FD14->~X():8(0)
00345A48->~X():8(0)
0012F7D8->X():-858993460(0)
00345AE0->X(X&):-842150451(0)
0012F7D8->~X():0(0)
0012F7D8->X():0(0)
00345AE4->X(X&):-842150451(0)
0012F7D8->~X():0(0)
0012F7D8->X():0(0)
00345AE8->X(X&):-842150451(0)
0012F7D8->~X():0(0)
0012F7D8->X():0(0)
00345AEC->X(X&):-842150451(0)
0012F7D8->~X():0(0)
0012FF04->X():-858993460(0)
0012FF08->X():-858993460(0)
00345B30->X(int):-842150451(9)
00345B30->~X():9(0)
00345B34->X():-842150451(0)
00345B38->X():-842150451(0)
00345B3C->X():-842150451(0)
00345B40->X():-842150451(0)
00345B44->X():-842150451(0)
00345B44->~X():0(0)
00345B40->~X():0(0)
00345B3C->~X():0(0)
00345B38->~X():0(0)
00345B34->~X():0(0)

I have thought more about the program and believe that on line 7: 'this' refers to the memory address, 's' refers to the name and type of the variable, 'val' refers to the value of the variable, I don't know what 'nv' refers to, perhaps array size.

So the when the global variable X glob(2) is created on line 36 it constructs a variable of size 2 at memory address 004241A0, name X and type int, of value 0. The address suggests to me that this variable was put in stack memory. Because it is global, it is never destroyed. That address is never written again.

I think line 37 copies 'glob(2)' to 'a', and 'a' is put into memory address 0012FF54, a heap memory address. It again has name X and is of type int. Line 38 copies 'a' to 'aa' and puts into memory address 0012FF48, again heap memory and the address is declining as heap addresses should (I think).

Am I in the ball park or way, way off?

The first hex value is the value of the this pointer. The next item after -> is the constructor that was called. If you look in each of the constructors you will find the string that was passed to the out() method -- nothing magical here. The last part in parentheses is the value of the struct's value integer.

I would recommend that you simply comment out all the code in main() and put the lines back in one at a time and check the output. This is a good exercise to understand how objects are created and assigned to values, but it is for you to work out by inspecting the output versus the code that executes. Afterwards, you will understand very well what is going on.. just keep staring at it and try to understand the logic.

@Mike,

That was an OUTSTANDING suggestion!! I never would have thought of it on my own because I had no intention of modifying Stroustrup's code.

Executing the lines of main() one at a time yielded very interesting results. I now have a much better understanding of the default constructor, explicit constructor, copy constructor, copy assignment, and destructor. Though I have almost as many new questions as old questions were answered. For example, line 67 where the vector is created yields lines 28-39 in the output. The vector is constructed in the stack, copied to the heap, then destroyed in the stack. This happens 4 times, so the construction and destruction is occurring for each element of the vector. I had no clue that was happening!

I think this was a very advanced exercise. Stroustrup has many exercises that are too advanced for programmers new to C++. I am very grateful for your comments because I would not have gotten as much out of this exercise, nor his book as a whole, without them. Thank you very, very much.

For example, line 67 where the vector is created yields lines 28-39 in the output. The vector is constructed in the stack, copied to the heap, then destroyed in the stack. This happens 4 times, so the construction and destruction is occurring for each element of the vector. I had no clue that was happening!

I think I should have written that the vector is constructed in the heap, copied to the stack, and then destroyed in the heap.

This question has already been answered. Start a new discussion instead.