Search code examples
cstringglibc

On better understanding the strncpy() function behavior


In the Linux manpage of strncpy I read:

If the length of src is less than n, strncpy() writes additional
null bytes to dest to ensure that a total of n bytes are written.

In this limit case (no \0 at the end of both strings) where n>4:

    char dest[8]="qqqqqqqq";
    char src[4] = "abcd";
    strncpy(dest, src, 5);

printing dest char by char gives "abcdqqqq". As src has no \0 in it, no \0 is copied from the src to dest, but if I understand correctly the man page, other 4 characters should be copied in any case, and they should be \0s. Moreover, if src is "abc" (so it is NUL terminated), dest contains "abc\0\0qqq". I add the whole code I used to test (yes it is going to the 8-th character to look at it also):

#include <stdio.h>
#include <string.h>

int main()
{
    char dest[8]="qqqqqqqq";
    char src[4] = "abcd"; //  "abc"
    strncpy(dest, src, 5);
    for (int i=0; i<9; i++)
        printf("%2x ", dest[i]);
    putchar('\n');

    return 0;
}

Is this a faulty implementation or do I miss something?


Solution

  • If the length of src

    That's the problem, your src is not a null terminated string so strncpy has no idea how long it is. The manpage also has a sample code showing how strncpy works: it stops at a null byte and if it doesn't find one it simply keeps reading until it reaches n. And in your case it reads the 4 characters of src and gets the fifth from dest because it's next in memory. (You can try printing src[4], nothing will stop you and you'll get the q from dest. Isn't C nice?)