In the case you describe, delete p and delete [] p are the same as far as free() goes, but some runtimes would complain if you dont put in [].
The [] means that the compiler should call the 'vector delete' destructor, which calls the destructor on each element of the array. delete with no brackets just calls the destructor. In other words...
"delete p"
means:
p->~int(); // call the destructor of the object, in this case an int, so it may be skipped by the compiler, but you get the idea...
free(p); // free the space
"delete [] p"
means
for (int i = 0; i < (allocatedsizeof(p) / sizeof(p)); i++)
p[i].~int(); // destruct the ith object
free(p);
(allocatedsizeof() I made up to mean "the allocated memory size of the pointer()")
So the space allocated by either is always the same, its the destructor calling that is the difference. Some compilers/runtimes track whether an allocate was for a single object or an array, so you need to match your new [] with delete [], even for things like ints that don't have destructors.