strstr crashes on NULL

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • linq936@hotmail.com

    #1

    strstr crashes on NULL

    Hi,
    I have the following code:

    #include <stdio.h>

    int main(void){
    char* str1 = "abc";
    char* str2 = '\0';
    if ( strstr(str1, str2) == NULL ){
    printf("yes\n") ;
    }
    else{
    printf("no\n");
    }

    return 0;
    }

    It crashes on strstr() call, so is it because none of strstr()
    parameter can be NULL?

  • Walter Roberson

    #2
    Re: strstr crashes on NULL

    In article <1184197966.126 134.202820@n2g2 000hse.googlegr oups.com>,
    <linq936@hotmai l.comwrote:
    I have the following code:
    >#include <stdio.h>
    >int main(void){
    char* str1 = "abc";
    char* str2 = '\0';
    if ( strstr(str1, str2) == NULL ){
    printf("yes\n") ;
    }
    else{
    printf("no\n");
    }
    >
    return 0;
    >}
    It crashes on strstr() call, so is it because none of strstr()
    >parameter can be NULL?
    Right. Your char* str2 = '\0' is setting str2 to a NULL pointer
    instead of to an empty string, which would be "" or "\0";
    '\0' happens to be an integral constant with value 0 and so is
    a valid NULL pointer initializer (if strange). In C89 at least,
    strstr() is not defined for the case of a NULL pointer
    (but is defined for the case of a pointer to an empty string.)

    --
    I was very young in those days, but I was also rather dim.
    -- Christopher Priest

    Comment

    • pete

      #3
      Re: strstr crashes on NULL

      linq936@hotmail .com wrote:
      >
      Hi,
      I have the following code:
      >
      #include <stdio.h>
      You're missing:
      #include <string.h>
      >
      int main(void){
      char* str1 = "abc";
      char* str2 = '\0';
      That's a bad way to write
      char* str2 = NULL;

      If you change that to
      char* str2 = "";
      then you can output "no".
      if ( strstr(str1, str2) == NULL ){
      printf("yes\n") ;
      }
      else{
      printf("no\n");
      }
      >
      return 0;
      }
      >
      It crashes on strstr() call, so is it because none of strstr()
      parameter can be NULL?
      Yes.

      --
      pete

      Comment

      • Keith Thompson

        #4
        Re: strstr crashes on NULL

        linq936@hotmail .com writes:
        I have the following code:
        >
        #include <stdio.h>
        >
        int main(void){
        char* str1 = "abc";
        char* str2 = '\0';
        if ( strstr(str1, str2) == NULL ){
        printf("yes\n") ;
        }
        else{
        printf("no\n");
        }
        >
        return 0;
        }
        >
        It crashes on strstr() call, so is it because none of strstr()
        parameter can be NULL?
        Yes. You may also be confused about the various meanings of "null".

        In your declaration

        char *str2 = '\0';

        you're not setting str2 to point to an empty string; you're setting it
        to a null pointer, which doesn't point to anything. If you wanted
        str2 to point to a empty string, you could have declared:

        char *str2 = "";

        Normally the character constant '\0' is used to refer to a null
        character, the character whose value is zero (sometimes called NUL
        with one 'L'). This is the character used to mark the end of a
        string.

        But as it happens, the character constant '\0' is exactly equivalent
        to the integer constant 0, and in this context it indicates a null
        pointer, not a null character. Using '\0' in this context isn't
        exactly wrong (the compiler is perfectly happy with it), but it's
        misleading. If you want a null pointer, it's better to use the NULL
        macro.

        So, you can either declare:

        char *str1 = "abc";
        char *str2 = NULL;

        (but then passing str2 to strstr invokes undefined behavior), or you
        can declare:

        char *str1 = "abc";
        char *str2 = "";

        In that case, strstr(str1, str2) will return the value of str1.

        I suggest you take a look at sections 4, 5, and 6 of the comp.lang.c
        FAQ, <http://www.c-faq.com/>.

        You also need to add a '#include <string.h>' to your program, since
        you're calling the strstr function. It may happen to work without it,
        but the #include directive is *not* optional. (A note to my fellow
        pedants: yes, he could declare strstr himself, but that would be
        silly.)

        --
        Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
        San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
        "We must do something. This is something. Therefore, we must do this."
        -- Antony Jay and Jonathan Lynn, "Yes Minister"

        Comment

        • linq936@hotmail.com

          #5
          Re: strstr crashes on NULL

          On Jul 11, 6:33 pm, Keith Thompson <k...@mib.orgwr ote:
          linq...@hotmail .com writes:
          I have the following code:
          >
          #include <stdio.h>
          >
          int main(void){
          char* str1 = "abc";
          char* str2 = '\0';
          if ( strstr(str1, str2) == NULL ){
          printf("yes\n") ;
          }
          else{
          printf("no\n");
          }
          >
          return 0;
          }
          >
          It crashes on strstr() call, so is it because none of strstr()
          parameter can be NULL?
          >
          Yes. You may also be confused about the various meanings of "null".
          >
          In your declaration
          >
          char *str2 = '\0';
          >
          you're not setting str2 to point to an empty string; you're setting it
          to a null pointer, which doesn't point to anything. If you wanted
          str2 to point to a empty string, you could have declared:
          >
          char *str2 = "";
          >
          Normally the character constant '\0' is used to refer to a null
          character, the character whose value is zero (sometimes called NUL
          with one 'L'). This is the character used to mark the end of a
          string.
          >
          But as it happens, the character constant '\0' is exactly equivalent
          to the integer constant 0, and in this context it indicates a null
          pointer, not a null character. Using '\0' in this context isn't
          exactly wrong (the compiler is perfectly happy with it), but it's
          misleading. If you want a null pointer, it's better to use the NULL
          macro.
          >
          So, you can either declare:
          >
          char *str1 = "abc";
          char *str2 = NULL;
          >
          (but then passing str2 to strstr invokes undefined behavior), or you
          can declare:
          >
          char *str1 = "abc";
          char *str2 = "";
          >
          In that case, strstr(str1, str2) will return the value of str1.
          >
          I suggest you take a look at sections 4, 5, and 6 of the comp.lang.c
          FAQ, <http://www.c-faq.com/>.
          >
          You also need to add a '#include <string.h>' to your program, since
          you're calling the strstr function. It may happen to work without it,
          but the #include directive is *not* optional. (A note to my fellow
          pedants: yes, he could declare strstr himself, but that would be
          silly.)
          >
          --
          Keith Thompson (The_Other_Keit h) k...@mib.org <http://www.ghoti.net/~kst>
          San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
          "We must do something. This is something. Therefore, we must do this."
          -- Antony Jay and Jonathan Lynn, "Yes Minister"
          Thanks.

          My intention is that I use '\0' to initialize a string so that later I
          can know its state. How about this code:

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

          int main(void){
          char str1[10], str2[10];

          memset( str1, '\0', 10);
          memset( str2, '\0', 10);

          strcpy(str1, "abc");
          if ( strstr(str1, str2) == NULL ){
          printf("yes");
          }
          else{
          printf("no");
          }

          return 0;
          }

          This code works fine on the same machine with same compiler, of
          course I see "no". I tried commenting out string.h include, it still
          works.

          So does this mean it is really an un-expected behavior?

          Comment

          • Richard Heathfield

            #6
            Re: strstr crashes on NULL

            linq936@hotmail .com said:

            <snip>
            My intention is that I use '\0' to initialize a string so that later I
            can know its state.
            An empty string is very different to a null pointer.

            const char *nullpointer = '\0';
            const char *emptystring = "\0";

            or, equivalently: const char *emptystring = "";
            How about this code:
            >
            #include <string.h>
            #include <stdio.h>
            >
            int main(void){
            char str1[10], str2[10];
            >
            memset( str1, '\0', 10);
            memset( str2, '\0', 10);
            That's fine, but this works just as well:

            char str1[10] = "", str2[10] = "";
            strcpy(str1, "abc");
            if ( strstr(str1, str2) == NULL ){
            Yes, that's fine now.
            This code works fine on the same machine with same compiler, of
            course I see "no".
            Yes - strstr is defined to return str1 if str2 is an empty string.
            I tried commenting out string.h include, it still
            works.
            It is true that the program may give the appearance of continuing to
            work when you chop off important bits, in much the same way that a used
            car continues to work (for a while) with sand in the carburettor.
            So does this mean it is really an un-expected behavior?
            The code you posted this time is fine. Perfectly well-defined.

            --
            Richard Heathfield <http://www.cpax.org.uk >
            Email: -www. +rjh@
            Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
            "Usenet is a strange place" - dmr 29 July 1999

            Comment

            • Keith Thompson

              #7
              Re: strstr crashes on NULL

              santosh <santosh.k83@gm ail.comwrites:
              linq...@hotmail .com wrote:
              [...]
              > strcpy(str1, "abc");
              > if ( strstr(str1, str2) == NULL ){
              > printf("yes");
              >
              Unless you terminate the string supplied to printf with a newline
              character, '\n', or call fflush(stdout), your output is not guaranteed
              to appear immediately
              [...]

              Actually, it's not guaranteed to appear *at all* unless the last
              character you write to stdout is a new-line. It's
              implementation-defined whether a text stream must end in a new-line.
              The standard doesn't say what happens if a text stream does require a
              trailing new-line and you don't provide one, so the behavior is
              undefined; you might get no output at all, or demons might fly out of
              your nose.

              This is another of those things that will *probably* work just the way
              you expect it to (the program will print "yes" or "no" without a
              new-line), but if you write it correctly in the first place, you don't
              have to worry about it.

              --
              Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
              San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
              "We must do something. This is something. Therefore, we must do this."
              -- Antony Jay and Jonathan Lynn, "Yes Minister"

              Comment

              Working...