user3292886
user3292886

Reputation: 1

How sprintf works in C

Linux Kernel = 2.6.32-41-generic #94-Ubuntu
Language : C

Code Snippet:

#include <stdio.h>
int main ()
{
    char buf[5];
    int index = 0;

    for (index = 0; index < 5; index++ )
    {
        sprintf(buf,"sud_%d", index);
        printf("for index = %d\n",index);
        printf("buf = %s\n",buf);
    }

    return 0;
}

Question1 : Why the above code snippet goes into loop while executing the above code?
Question2 : Does sprintf requires its last bit of the target buffer to be filled with 0 or '\0' ?

if I made the buffer size 6 (buf[6]) in the above code, it works fine.

can anyone please let me know the reason of this behavior?

Regards, Sudhansu

Upvotes: 0

Views: 1673

Answers (2)

unwind
unwind

Reputation: 400159

Because undefined behavior.

The output buffer buf is only 5 characters big, but the first call to sprintf() will generate the string "sud_0", which requires 6 characters due to the terminator. It then writes outside of buf, triggering undefined behavior. Use snprintf().

snprintf() doesn't "require" the last character to be filled with anything before you call it, but it will make sure it's set to '\0' after the call has completed. This is because it aims to build a complete and valid C string in the given buffer, and thus it must make sure the string is properly terminated.

It's hard (and some would say pointless) to reason about undefined behavior, but I suspect that what happens is that the 6th character written into buf overflows into index, writing the first byte to 0. If you're on a little-endian system, this will be the same as doing index &= ~255. Since the value of index is just supposed to be between 0 and 5, it's reset to 0 which causes the loop to go on for ever.

Upvotes: 4

Dariusz
Dariusz

Reputation: 22311

You are writing outside declared buffer. That is undefined behavior.

Your char buf[5]; is too small. You require at least 6 chars for "sud_0" because of the '\0' terminator.

Upvotes: 3

Related Questions