this change is made with some reluctance, but i think it's for the
best. correct programs must handle either behavior, so there is little
advantage to having malloc(0) return NULL. and i managed to actually
make the malloc code slightly smaller with this change.
do not allow allocations that overflow ptrdiff_t; fix some overflow
checks that were not quite right but didn't matter due to address
layout implementation.