A new is basically a wrapped malloc. The compiler is allowed to use stdio functions at will, for example if you try and implement your own memcpy you'll get some weird recursion. If the compiler sees you copying more than a certain amount (say a dumb bit-for-bit copy constructor) it will use memcpy.
So yes, new is sort of a lie, new means "allocate some memory and construct something there and let me write it as one thing", if you allocate an array of floats say, they are uninitialised, malloc will probably be directly used.
Notice I say probably, I'm not sure if they're set to zero these days :P
Anyway, all compiler optimisations ('cept copy elisioning and other return-value-optimisation stuff - BUT THIS IS THE ONLY EXCEPTION) are invisible to you, that is the point. The program cannot tell it was optimised, you'd have to be timing it and stuff. For example:
(x*10)/2
This will not be optimised if the compiler has no idea about the range of x, because x*10 could overflow, but x*5 might not. So if it optimised it'd change the result.
if(x>0 && x<10) {
(x*10)/2
}
will become x*5 because the compiler, being really smart (much more than this) sees "there's no way x*10 can overflow, so x*5 is safe."
If you have a global new/delete that you defined, the compiler cannot optimise because it cannot know it'll have no effects if it does. If you define your own everything it "simplified" to malloc/free will go away.
NOTE:_
I've deliberately ignored the malloc and type-saftey stuff. It's not relevant.
The compiler assumes that malloc, free, memcpy and so forth are all super-optimised and will use them ONLY WHERE SAFE - as described above. There's a GCC thread on the mailing list somewhere where I learned of the memcpy thing.