smalloc: zero size allocs may need to be free'd

Zero size allocations don't necessarily mean that data == NULL. So
instead check each value seperately and perform necessary operations.
smalloc: call callback if set on AllocDispose

Fix bug where if dev passed a callback to Alloc then called AllocDispose
it wouldn't bother to pass the data to the callback and instead would
just free it.