#include <iostream>

// The moral of the story: It's not enough to delete all the addresses
// that you get from new.  You must also ensure that the type of the
// pointers passed to delete match the type they were new-ed with.

class A {
public:
	char a;
        A(char x) : a(x) { std::cerr <<  "A" << a << std::endl; }
        ~A()             { std::cerr << "~A" << a << std::endl; }
};

class V {
public:
	char a;
        V(char x) : a(x) { std::cerr <<  "A" << a << std::endl; }
        virtual ~V()     { std::cerr << "~A" << a << std::endl; }
};

char *chardup(char x)
{
	char *n = new char;
	*n = x;
	return n;
}

int main()
{
	char* a = (char*) new   A('a');
	char* b = (char*) new   A('b');
	char* c =         chardup('c');
	A*    d =         new   A('d');
	A*    e = (A*)    chardup('e');
	A*    f = (A*)    chardup('f');

	char* g = (char*) new   A('g');
	char* h = (char*) new   A('h');
	char* i =         chardup('i');
	V*    j =         new   V('j');
	V*    k = (V*)    chardup('k');
	V*    l = (V*)    chardup('l');

	delete (A*)    a;
	delete         b;
	delete         c;
	delete         d;
	delete (char*) e;
	delete         f;
	//delete (V*)  g;	// crashes
	delete         h;
	delete         i;
	delete         j;
	delete (char*) k;
	//delete       l;	// crashes
}

/* Output:

Aa
Ab
Ad
Ag
Ah
Aj
~Aa
~Ad
~Af
~Aj

*/

