El problema es que el destructor se está invocando dos veces, y entonces
delete [] elem; se ejecuta dos veces también, y es ahí donde se produce:
Cita: *** glibc detected *** ./ejemplo: double free or corruption (fasttop): 0x080f4008 ***
(Y lo dice con todas las letras: "double free")
Código:
int main()
{
C a(5);
// a.~C(); // comenta esto
return 0;
} // acá es donde se invoca al destructor de a
"a" es una variable local de main(), y cuando sale de ámbito (scope), se invoca su destructor.
Sólo en casos muy, pero muy, particulares se necesita invocar un destructor explícitamente.
Lareto :)