Thread: null termination with str(n)cpy and strlen

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    72

    null termination with str(n)cpy and strlen

    Hi All

    I've written a program which runs fine, but I noticed something which worries me a little bit. Here is a simplified snippet:

    Code:
    char* src = "HELLO" ; 
    int len = strlent(src) ;
    char* dest = malloc( len * sizeof(char) ) ; 
    strncpy(dest, src, len) ;
    printf("src=%s, dest=%s\n", src, dest) ;
    strlen returns the length of the string without the null termination. So I would say you have to do
    Code:
    ....
    char* dest = malloc( len * sizeof(char) + 1 ) ;
    strncpy(dest, src, len + 1) ; // so it copies the null terminator too
    Is this a correct statement ?
    If so, why doesn't this cause any runtime errors in my program ?

    thnx
    LuCa

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    #1) Just because you don't get an error doesn't mean the code is bug-free; the errors those bugs could cause may show up later, if you add to the program or use a different compiler/different computer.

    But you are right about using the +1 to include the \0.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    72
    are you sure you need +1 for strncpy ?

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by jeanluca View Post
    are you sure you need +1 for strncpy ?
    In this case I think so:

    Quote Originally Posted by GNU Reference
    char * strncpy (char *restrict to, const char *restrict from, size_t size)

    If the length of from is more than size, then strncpy copies just the first size characters. Note that in this case there is no null terminator written into to.

    If the length of from is less than size, then strncpy copies all of from, followed by enough null characters to add up to size characters in all. This behavior is rarely useful, but it is specified by the ISO C standard.
    It doesn't actually say what would happen if they are the same size, but I would presume the former.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    You are correct in using:

    Code:
       strncpy(dest, src, len + 1) ; // so it copies the null terminator too

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    By the way, sizeof(char) is always equal to 1. If you feel that the sizeof is necessary, it would be better to write:
    Code:
    char* dest = malloc( len * sizeof(*dest) );
    on account that the result of sizeof would be appropriate to the type of dest, and an error is more likely should the name of the pointer be changed.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    If you are dynamically allocating the memory to ensure the destination buffer has enough space to fit the string, there is no need to use strncpy(). In this case (as in your example), you can just use strcpy().

  8. #8
    Registered User
    Join Date
    May 2009
    Posts
    72
    thnx a lot for helping! this will give me a good start

  9. #9
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    And also check the return value of malloc. Better to do some error handling.

    -ssharish
    Life is like riding a bicycle. To keep your balance you must keep moving - Einstein

  10. #10
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    Quote Originally Posted by bithub View Post
    If you are dynamically allocating the memory to ensure the destination buffer has enough space to fit the string, there is no need to use strncpy(). In this case (as in your example), you can just use strcpy().
    I want to echo this good advice, I feel like it's being lost in the thread.

    Quote Originally Posted by slingerland3g
    You are correct in using:
    Code:
    strncpy(dest, src, len + 1) ; // so it copies the null terminator too
    Make sure you have room in the buffer. But why not just call strcpy()? (or, since you know the length, memcpy()?) If you just want to duplicate the string:

    Code:
    const char *src_string;
    char *dst_string
    Code:
    // Quite possibly the easiest way...
    // If your system doesn't have strdup(), write one.
    dst_string = strdup(src_string);
    or
    Code:
    dst_string = malloc(strlen(src_string) + 1);
    if(!dst_string)
    	// No memory.
    strcpy(dst_string, src_string);
    or
    Code:
    size_t len = strlen(src_string);
    dst_string = malloc(len + 1);
    if(!dst_string)
    	// No memory.
    // If strncpy() actually copies n chars, this will null terminate.
    dst_string[len] = 0;
    strncpy(dst_string, src_string, len);
    Last edited by Cactus_Hugger; 06-22-2009 at 03:54 PM.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function error
    By GaPe in forum C Programming
    Replies: 10
    Last Post: 02-16-2003, 11:12 PM