How to Fix: 'sprintf' Writing a Terminating Nul Past the End of the Destination

In my C application, I wanted to convert a byte (stored as an unsigned char) into a hexadecimal string. To do so, I wrote the following code:

1char hex[2];
2unsigned char byte = 10;
3sprintf(hex, "%02X", byte);

However, the code produced unreliable results. Moreover, the compiler threw the following warning:

I fixed both of these issues by changing the size of the char array hex from two to three bytes, like so:

1char hex[3];
2unsigned char byte = 10;
3sprintf(hex, "%02X", byte);

Still, I couldn’t understand why it solved my problem: after all, the hexadecimal string of my byte should make up two chars, not three. Through my research, I stumbled upon the following definition of the sprintf function in the C11 standard:

The sprintf function is equivalent to fprintf, except that the output is written into an array (specified by the argument s) rather than to a stream. A null character is written at the end of the characters written (emphasis mine); it is not counted as part of the returned value. If copying takes place between objects that overlap, the behavior is undefined.

In other words, as the compiler warned me, the array hex was too small for sprintf to properly append the NUL char (\0). Changing the size of the array from two to three bytes allowed sprintf to output the hexadecimal and NUL chars. The NUL char matters because it is used to indicate the end of a string in C. More information about strings in C can be found on Tutorials Point.