Playing with Memory in C++

by Elben Shira

I gave a two-hour lecture over C++ a couple of months ago. It was oriented towards Java programmers, so naturally I bashed in pointers and stack versus heap memory allocations into their heads. One of the examples I demoed was this:

// The outputs given is based on my machine; it may
// be different on yours.

#include <iostream>
using namespace std;

int main() {
  int *p = new int(144);
  cout << *p << endl;   // output: 144

  delete p;
  cout << *p << endl;   // output: 144 (weird?)

  char *z = new char('a');
  cout << *p << endl;   // output: 97 (crazy!)
  // note: 97 is the numerical representation of 'a'.

  delete z;
  return 0;
}

This example reveals how a pointer works internally. After line 11, we have no guarantee about what data p points to, so we should not use p ever again. But because we are evil programmers, we output *p on line 12 and line 15 and get unexpected but entertaining results. Why is 144 the output of line 12 even though p was deleted? And what is up with the output of line 15?

The keyword delete takes, as an argument, a pointer. In reality, delete doesn’t actually delete anything. Instead, delete lets the operating system know that the memory blocks (on the heap) the pointer is pointing to are now up for grabs. That is, new data can replace the “deleted” data. But we do not add any new data onto the heap before line 12, so the value 144 is never replaced. This is why line 12 still outputs 144.

Line 14 creates a new character ‘a’ on the heap. We have no control over where ‘a’ is placed in memory. On my machine, however, the operating system decided to put ‘a’ at the exact memory address where 144 used to be. As a result, when we print out *p, we get 97, which is the ASCII numerical representation of ‘a’.

Fun stuff.