I was asked this in an interview today:
Q: malloc(0); /* What does it do? */
It's a great question because it covers a subtlety in the standard and a condition that not many people will consider. Unfortunately, I wasn't 100% confident that I remembered what the standard said about it. With full understanding that I brought the question on myself by arrogantly describing myself as an expert in C, I gave my answer as follows: "A valid pointer will be returned, but that pointer cannot be dereferenced."
My answer was wrong. The interviewer said that the result was undefined behavior, which seemed slightly off to me at the time though I didn't challenge him on a nuance I wasn't assured of. As it turns out, my answer was partially correct, though in being partially correct it was still wrong. However, the interviewer wasn't correct either. The standard states the condition of a zero size request as follows:
"If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object."
Note that implementation-defined is very different from undefined. Undefined means that the very act of calling malloc(0)
invokes undefined behavior and as a result makes the entire program henceforth undefined as well. Implementation-defined means that malloc(0)
is legal and doesn't affect the legality of the rest of the program, but you must take all possible results into account when making the call if you want your code to be portable. As such, the following is portable and legal, but completely useless because the pointer cannot be dereferenced:
p = malloc(0);
if (!p)
{
/* Don't dereference p */
}
else
{
/* Still don't dereference p */
}
If malloc(0)
were undefined, the above code would be horribly broken...and still completely useless. ;) The reason my partially correct answer was wholely wrong is I neglected to account for one of two possible outcomes. And while the interviewer was technically incorrect in saying that malloc(0)
is undefined, he was practically correct because thinking of a useless situation as being undefined keeps you from creating that situation. In practice, he'd potentially write better code by avoiding sending in a zero size than by accounting for the implementation-defined behavior of sending in a zero size.
Robust code is the goal. I'm not sure there's a lesson to be learned from this interview, but it is what it is. Discuss. :)