The trivial case which you show can be detected at compile time, because the instantiation and destruction of the object are in the same scope. In general, the deletion is no in the same scope, or even the same source file, as the instantiation.
And a C++ pointer's type does not carry information about whether it references a single object of its type or an array, let alone the allocation scheme. So it is not possible to diagnose this at compile time in general.
Why not diagnose the special cases that are possible?
In C++ there are already tools for dealing with leakage of dynamic resources that are tied to scopes, namely smart pointers and higher level arrays (
Even if you use the correct
delete flavor, your code is still not exception safe. If the code between the
delete terminates by a dynamic exit, the deletion never executes.
As far as run-time detection goes, the
Valgrind tool does a good job of detecting this at run-time. Watch:
==26781== Command: ./a.out
==26781== Mismatched free() / delete / delete 
==26781== at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26781== by 0x8048498: main (in /home/kaz/test/a.out)
==26781== Address 0x4324028 is 0 bytes inside a block of size 80 alloc'd
==26781== at 0x402B454: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26781== by 0x8048488: main (in /home/kaz/test/a.out)
Of course, Valgrind doesn't run on all platforms, and it's not always practical or possible to reproduce all run-time situations under the tool.