Weird strlen behavior

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Chris

    #1

    Weird strlen behavior

    Hi there,

    I have been reading in this group for a while really enjoy this pool
    of infinite c wisdom. :)

    Anyway, I have question now. I have this little piece of code that is
    giving me a headache.

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

    /* Definitions */
    #define STRING_LENGTH 12

    /* Variables */
    char str[STRING_LENGTH];
    char *str1;
    char *str2 = &str[0];
    unsigned int i;

    /* Main */
    int main(void)
    {
    str1 = "Hello World!";

    printf("String length: %d\n",strlen(st r1));

    for(i = 0u; i < strlen(str1); i++)
    {
    *str2++ = *str1++;
    printf("%d\n",i );
    }

    puts(str);

    /* Wait for key */
    getc(stdin);
    return EXIT_SUCCESS;
    }

    The problem is the strlen(str1) expression. The code compiles fine
    (with latest MinGW under XP) but running the executable it gives me
    the following output:

    String Length: 12
    0
    1
    2
    3
    4
    5
    Hello

    It seems to break out of the loop early, after 6 iterations instead of
    12.

    I replace the expression with something like this:

    unsigned int length;

    ....

    length = strlen(str1);

    for(i = 0u; i < length; i++)
    {
    *str2++ = *str1++;
    printf("%d\n",i );
    }

    ....

    Then it works fine and runs 12 times and copies the entire string.

    Any idea whats the problem here?

    Thanks,
    Chris

  • Eric Sosman

    #2
    Re: Weird strlen behavior

    Chris wrote:
    Hi there,
    >
    I have been reading in this group for a while really enjoy this pool
    of infinite c wisdom. :)
    >
    Anyway, I have question now. I have this little piece of code that is
    giving me a headache.
    >
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    >
    /* Definitions */
    #define STRING_LENGTH 12
    >
    /* Variables */
    char str[STRING_LENGTH];
    char *str1;
    char *str2 = &str[0];
    unsigned int i;
    >
    /* Main */
    int main(void)
    {
    str1 = "Hello World!";
    >
    printf("String length: %d\n",strlen(st r1));
    >
    for(i = 0u; i < strlen(str1); i++)
    {
    *str2++ = *str1++;
    printf("%d\n",i );
    }
    >
    puts(str);
    >
    /* Wait for key */
    getc(stdin);
    return EXIT_SUCCESS;
    }
    >
    The problem is the strlen(str1) expression. The code compiles fine
    (with latest MinGW under XP) but running the executable it gives me
    the following output:
    >
    String Length: 12
    0
    1
    2
    3
    4
    5
    Hello
    >
    It seems to break out of the loop early, after 6 iterations instead of
    12.
    >
    I replace the expression with something like this:
    >
    unsigned int length;
    >
    ...
    >
    length = strlen(str1);
    >
    for(i = 0u; i < length; i++)
    {
    *str2++ = *str1++;
    printf("%d\n",i );
    }
    >
    ...
    >
    Then it works fine and runs 12 times and copies the entire string.
    >
    Any idea whats the problem here?
    You keep changing what str1 points to, and hence
    changing the result of strlen(str1):

    i = 0, strlen("Hello world!") = 12
    i = 1, strlen("ello world!") = 11
    i = 2, strlen("llo world!") = 10
    i = 3, strlen("lo world!") = 9
    i = 4, strlen("o world!") = 8
    i = 5, strlen(" world!") = 7
    i = 6, strlen("world!" ) = 6, that's all she wrote.

    Incidentally, you should be glad that your loop stopped early.
    The destination array str is twelve characters long, which is
    enough room for a string of *eleven* characters plus the zero
    end-marker. In your modified code you copy twelve characters
    from "Hello world!" to the destination, but there is no end-
    marker and the destination thus doesn't hold a proper string.
    Pass this malformed string to a function expecting a well-
    formed string (puts(), for example), and there's no telling
    what will happen.

    --
    Eric Sosman
    esosman@acm-dot-org.invalid

    Comment

    • Chris

      #3
      Re: Weird strlen behavior

      On Mar 3, 2:34 pm, Eric Sosman <esos...@acm-dot-org.invalidwrot e:
      You keep changing what str1 points to, and hence
      changing the result of strlen(str1):
      >
      i = 0, strlen("Hello world!") = 12
      i = 1, strlen("ello world!") = 11
      i = 2, strlen("llo world!") = 10
      i = 3, strlen("lo world!") = 9
      i = 4, strlen("o world!") = 8
      i = 5, strlen(" world!") = 7
      i = 6, strlen("world!" ) = 6, that's all she wrote.
      Doh! Thanks.
      Incidentally, you should be glad that your loop stopped early.
      The destination array str is twelve characters long, which is
      enough room for a string of *eleven* characters plus the zero
      end-marker. In your modified code you copy twelve characters
      from "Hello world!" to the destination, but there is no end-
      marker and the destination thus doesn't hold a proper string.
      Pass this malformed string to a function expecting a well-
      formed string (puts(), for example), and there's no telling
      what will happen.
      Thats correct. I always forget that little invisible sucker...

      Thanks for the quick response.

      Chris

      Comment

      Working...