problem with strlen

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • happyefforts
    New Member
    • Sep 2010
    • 1

    problem with strlen

    Code:
    void show1(char *s) {
      int i;
      for (i = 0; i < strlen(s); i++) printf("%c", s[i]);
      printf("\n");
    }
    
    void show2(char *s) {
      int i;
      for (i = 0; i <= strlen(s) - 1; i++) printf("%c", s[i]);
      printf("\n");
    }
    When I do show1(""), it has no problem. But show2("") gives me a error. Anyone know why?
  • Markus
    Recognized Expert Expert
    • Jun 2007
    • 6092

    #2
    The string length (strlen) of "" is 0 (strlen = 0)
    strlen - 1 = -1
    s[-1] is accessing data to which your not permitted access. This is a fundamental part of working with memory in C.

    Comment

    • Banfa
      Recognized Expert Expert
      • Feb 2006
      • 9067

      #3
      Close Markus, it never tries to access s[-1], although you are right about the condition causing the problem.

      strlen(s) - 1 for s == "" == -1

      Therefore the condition is i <= -1

      Since i is initialised to 0 on a 32 bit system that allows i to have the range 0 - 2147483647 until i final wraps and causes undefined behaviour (for wrapping a signed integer).

      However since s has length 0 as soon as i >= 1 you are accessing memory outside the bounds of the array and at some point in the 2147483646 out of bounds addresses it tries I expect it hits something that really causes a problem.


      For this reason if you have a size (especially if it can be 0) for something SIZE and are range testing you should always use

      range < SIZE

      and not

      range <= SIZE - 1

      I have seen this in a production product cause the same problem.

      Comment

      • donbock
        Recognized Expert Top Contributor
        • Mar 2008
        • 2427

        #4
        What error do you get for show2?

        Banfa: if strlen(s)-1 evaluated to -1 then execution would skip over the loop. There would be no output or run-time error.

        strlen returns size_t, which is typically an unsigned type.

        Is the expression (strlen(s) - 1) evaluated for type size_t or type int? If size_t, then -1 is considered to be a very large positive number that is too large to fit in an int (for a 2's-complement architecture). If int, then the result is truly -1.

        The comparison of i to the expression is performed using int arithmetic. If the expression is of type size_t then the very large positive number is converted to int. The result of this conversion may be a positive number or a negative number, depending on implemention-dependent properties of the compiler.

        At least that's what I think might be going on.

        Comment

        • Markus
          Recognized Expert Expert
          • Jun 2007
          • 6092

          #5
          Of course, now I see it.

          Mark (shouldn't rush to answer things).

          Comment

          Working...