0
int main() {
    char src[] = "santosh";
    char dest[0];
    strncpy(dest, src, 4);
    printf("%s\n", dest); // expecting o/p "sant" but o/p was "santtosh"
    int i = 0;
    while (dest[i]) {
        printf("%c", dest[i]);   //expecting output "sant" but it was "santtosh"
        i++;
    }

    printf("\n");
    i = 0;

    while (src[i]) {
        printf("%c", src[i]); // expecting o/p "santosh" but it was "anttosh"
        i++;
    }
    return 0;
}

I am having trouble with this code, I run the code using gcc compiler and here is output I got(comment section). Why behavior is not as per the expectation? why strncpy() is able to copy source string even if dest buff is not enough?

  • 6
    `char dest[0]` <- pretty much your entire program is undefined behaviour at this point. What you're saying with that declaration is that the `dest` array is a *fixed* size of 0 characters. Therefore it can never contain anything and any access to it (read *or* write) is undefined. – Greg Hewgill Nov 27 '16 at 20:16
  • 2
    Named after a British pop band **UB40**... You should also consider removing the `c++` tag. –  Nov 27 '16 at 20:16
  • 1
    It's undefined behaviour. C will let you write anywhere you want, and it's up to you to decide if you should... – Charles Nov 27 '16 at 20:18
  • drive on the wrong side of the road, you could survive a few minutes. But it doesn't mean that it's the correct way to do it. – Jean-François Fabre Nov 27 '16 at 20:19
  • Even if the target buffer was big enough, this use of `strncpy` would be wrong. Before you use `strncpy` read about and understand what it does. It is **not** a "safe" replacement for `strcpy`. – Pete Becker Nov 27 '16 at 20:37

1 Answers1

1

Your code invokes undefined behavior, trying to explain why it produces some output or another is pointless.

Here are the problems:

  • You do not include <stdio.h>, nor <string.h>. Calling functions that have not been previously defined is not OK. Include the proper header file to avoid undefined behavior.

  • char dest[0]; defines an array with a size of 0. Such an object cannot be accessed, not even its address is meaningful. gcc and clang allow this, but as an extension to the C Standard. This definition looks like a typo, use gcc -Wall -W or clang -Weverything to enable useful warnings that will prevent such silly bugs.

  • strncpy(dest, src, 4); invokes undefined behavior since the length of dest is less than 4. Note that the behavior would still be error prone if dest had a length of 4 since strncpy would not null terminate the destination array if the source string's length is greater or equal to the size argument. Here "santosh" has a length of 7, so dest would hold the characters s, a, n and t, but no null terminator. Your while loop would invoke undefined behavior as while (dest[i]) would access dest beyond its size. strncpy() is error prone, its semantics are widely misunderstood and cause bugs very easily. Do not use this function.

  • As explained above, while (dest[i]) invokes undefined behavior because dest cannot be dereferenced as currently defined or even if it were defined as char dest[4];.

Here is an improved version, using snprintf() and strncat():

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

int main(void) {
    char src[] = "santosh";
    char dest[5];

    *dest = '\0';
    strncat(dest, src, 4);
    printf("%s\n", dest);        // will output "sant"
    for (int i = 0; dest[i]; i++) {
        printf("%c", dest[i]);   // will output "sant" too
    }
    printf("\n");

    snprintf(dest, sizeof dest, "%s", src);
    printf("%s\n", dest);        // will output "sant"
    for (int i = 0; dest[i]; i++) {
        printf("%c", dest[i]);   // will output "sant" again
    }
    printf("\n");

    for (int i = 0; src[i]; i++) {
        printf("%c", src[i]);    // will output "santosh"
    }
    printf("\n");

    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189