I hope this does more to help than to confuse, but here goes another answer. The original question was; which is the same as free(), delete or delete[]? It turns out that none of the three are equal. free() simply "returns" the block of memory back to the pool of available memory while delete "knows" if a destructor needs to be called first. delete[] will call the destructor for each object in an array if needed, before "returning" the memory to the pool of available memory. It is also important to match calls of malloc() with free(), new with delete and new[] with delete[].
Just to point some thing s out, posting #3 is filled with unpredictable behavior. The fact that it's unpredictable is why the different compilers don't react to it the same.
1. a could start out pointing to any memory address (in the stack, in the heap, anywhere).
2. The code will then print out the address of n, not the value. (forgot the semicolon )
3. n could be any integer value, there's no telling how many times this thing is going to loop for.
4. now "a[i] = i" is just writing to some location in memory. Hopefully it doesn't write over anything important like a return address.
5. It's a long shot, but possible that "a[i] = i" wrote over the value of n. This may loop a different number of times from before.
6. Most of the time, this will print out the numbers 0 1 2 3... for however many n now holds the value of.
This code also "works" for strings because strings are just arrays of 1 or 2 byte integers (char or wchar_t respectively) in c/c++. It has little chance of actually working with the desired string length in any way though.
Hopefully this sheds some light on what this code is doing.