The current implementations of the memory allocation functions mistake a nullptr returned from std::malloc, std::calloc, or std::realloc as a failure. The behaviour for each of std::malloc, std::calloc, and std::realloc when the size is 0 is implementation defined, and may return a nullptr.
If the system function returns nullptr, check if the size is 0 and return a non-null pointer using malloc.
Suggested comment before this line (and similarly for the other two functions):