The Perils of strncpy()

Always be careful when manipulating strings! Tack on that null character, '\0', at the end of a string! And don’t worry about the C language string functions: They perform this important feature for you. But do they all?

Well, not really.

I discovered an issue when I recently used the strncpy() function and found some peculiar output. Not understanding why my output string had extra characters, I perused the man pages and discovered this warning:

The stpncpy() and strncpy() functions copy at most len characters from src into dst. If src is less than len characters long, the remainder of dst is filled with `\0' characters. Otherwise, dst is not terminated.

That last line is significant. When the number of characters copied is shorter than the string being copied, a null character is not added. Therein you find potential for weird strings — and perhaps some unintended buffer overflow.

Here is sample code that illustrates the problem:

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

int main()
{
    char source[] = "My text will be copied";
    char destination[] = "123456789012345678901234567890";

    strncpy(destination,source,7);
    printf("%s\n",destination);

    return(0);
}

At Line 9, only 7 characters of string source are copied into string destination. Because source is longer than 7 characters, the null character isn’t appended. Here’s the output:

My text89012345678901234567890

If the destination buffer is uninitialized, the output is unpredictable, spewing forth whatever garbage is in the buffer. This effect is what I saw in my test program.

The following code shows what happens with the source string is shorter than the length of bytes copied:

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

int main()
{
    char source[] = "My text will be copied";
    char destination[] = "123456789012345678901234567890";

    strncpy(destination,source,25);
    printf("%s\n",destination);

    return(0);
}

String source is only 22 characters long. Hopefully the strncpy() function is wise enough to see that it terminates before all 25 characters are copied into the destination buffer. Here’s the output:

My text will be copied

The string is copied and terminated as it’s declared; no extra characters are copied. The null character prevents the remainder of the text in the destination buffer from appearing.

I tried to rack my brain to figure out why the null character isn’t added when the source string is longer than the characters copied. A good reason must exist or they wouldn’t have written the function as it is. If you can figure out why such a feature is useful, let me know. I’m sure some valid purpose exists.

2 thoughts on “The Perils of strncpy()

  1. Maybe it’s to allow for string concatentation. You would only want \0 at the end of the last string to be concatenated so you could malloc/realloc just enough memory for each string to be added until you get to the last one when you’d realloc strlen + 1 to allow for the \0.

    I didn’t explain that very well so let me know if you want some code to illustrate what I’m trying to say.

  2. You made me think of another purpose (or side effect): Insertion or substitution.

    Still, it seems odd with so many null-terminated string functions that this one has a particular quirk.

Leave a Reply