Looks like operator new and operator new[] have exactly the same signature:
void* operator new( size_t size );
void* operator new[]
One purpose is that they can be separately defined by the user. So if I want to initialize memory in single heap-allocated objects to 0xFEFEFEFE and memory in heap-allocated arrays to 0xEFEFEFEF, because I think it will help me with debugging, then I can.
Whether that's worth it is another matter. I guess if your particular program mostly uses quite small objects, and quite large arrays, then you could allocate off different heaps in the hope that this will reduce fragmentation. But equally you could identify the classes which you allocate large arrays of, and just override operator new[] for those classes. Or operator new could switch between different heaps based on the size.
There is actually a difference in the wording of the requirements. One allocates memory aligned for any object of the specified size, the other allocates memory aligned for any array of the specified size. I don't think there's any difference - an array of size 1 surely has the same alignment as an object - but I could be mistaken. The fact that by default the array version returns the same as the object version strongly suggests there is no difference. Or at least that the alignment requirements on an object are stricter than those on an array, which I can't make any sense of...