strtok causes Segmentation fault

Discussion in 'C Programming' started by bofh1234@hotmail.com, May 11, 2006.

  1. Guest

    I need to delimit a string. The delimiters are a semicolon and comma.
    When I run the program I get a segmentation fault on the first strtok.
    I followed the examples of others and from my old C books, but I can't
    seem to find the problem. The accesslist has a format of
    20,45;22,44;46,28;99,43,etc. What am I doing wrong?
    Thanks,

    #include <sys/signal.h>

    #include <messages.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <ctype.h>

    #define or ||
    #define and &&

    int createvarible(const int sock, char *name, char *type, char *value,
    char *list)
    {
    int n=0, size, returnval=0;
    char *tokenptr=NULL, *tokenptr2=NULL;
    int accesscode, portnum;

    tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?

    if (tokenptr == NULL) {
    tokenptr2 = strtok(list, ",");//delimit accesscode as there is no
    semicolon
    accesscode=atoi(tokenptr2);
    tokenptr2 = strtok(NULL, ",");//delimit port
    portnum=atoi(tokenptr2);
    printf("code[0] %d\n", accesscode);
    printf("port[0] %d\n", portnum); }
    else {
    while (tokenptr != NULL) { //don't worry about the code down here it
    does what I need
    tokenptr2 = strtok(list, ";");//delimit accesscode
    accesscode=atoi(tokenptr2);
    tokenptr2 = strtok(NULL, ",");//delimit portnum
    portnum=atoi(tokenptr2);
    printf("code[0] %d\n",accesscode);
    printf("port[0] %d\n",portnum);
    n++;
    }
    }
    return accesscode;
    }
     
    , May 11, 2006
    #1
    1. Advertising

  2. wrote:
    > I need to delimit a string. The delimiters are a semicolon and comma.
    > When I run the program I get a segmentation fault on the first strtok.
    > I followed the examples of others and from my old C books, but I can't
    > seem to find the problem. The accesslist has a format of
    > 20,45;22,44;46,28;99,43,etc. What am I doing wrong?
    > Thanks,
    >
    > #include <sys/signal.h>
    >
    > #include <messages.h>
    > #include <stdio.h>
    > #include <string.h>
    > #include <stdlib.h>
    > #include <unistd.h>
    > #include <ctype.h>
    >
    > #define or ||
    > #define and &&
    >
    > int createvarible(const int sock, char *name, char *type, char *value,
    > char *list)
    > {
    > int n=0, size, returnval=0;
    > char *tokenptr=NULL, *tokenptr2=NULL;
    > int accesscode, portnum;
    >
    > tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?
    >

    Is list non-null when first used as an arg to strtok()? Is it
    null-terminated?
     
    void * clvrmnky(), May 11, 2006
    #2
    1. Advertising

  3. Joe Smith Guest

    "void * clvrmnky()" <> wrote in message
    news:KEL8g.21456$!nnrp1.uunet.ca...
    > wrote:
    >> I need to delimit a string. The delimiters are a semicolon and comma.
    >> When I run the program I get a segmentation fault on the first strtok.
    >> I followed the examples of others and from my old C books, but I can't
    >> seem to find the problem. The accesslist has a format of
    >> 20,45;22,44;46,28;99,43,etc. What am I doing wrong?
    >> Thanks,
    >>
    >> #include <sys/signal.h>
    >>
    >> #include <messages.h>
    >> #include <stdio.h>
    >> #include <string.h>
    >> #include <stdlib.h>
    >> #include <unistd.h>
    >> #include <ctype.h>
    >>
    >> #define or ||
    >> #define and &&
    >>
    >> int createvarible(const int sock, char *name, char *type, char *value,
    >> char *list)
    >> {
    >> int n=0, size, returnval=0;
    >> char *tokenptr=NULL, *tokenptr2=NULL;
    >> int accesscode, portnum;
    >>
    >> tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?
    >>

    > Is list non-null when first used as an arg to strtok()? Is it
    > null-terminated?


    Non Standard stuff. Could this question have been framed so as to be
    topical in clc? Joe
     
    Joe Smith, May 11, 2006
    #3
  4. Guest

    Here is how I call createvarible:
    createvarible(ss, "xyz", "string", "this is a test",
    "22,43;44,33")
    So to answer your question the string is null terminated. To null
    terminate the string I think I have to put \0 at the end right?

    Thanks,
     
    , May 11, 2006
    #4
  5. Guest

    Changing the function call to createvarible(ss, "xyz", "string", "this
    is a test",
    "22,43;44,33\0") still causes a seg fault.
     
    , May 11, 2006
    #5
  6. Nelu Guest

    wrote:
    > Changing the function call to createvarible(ss, "xyz", "string", "this
    > is a test",
    > "22,43;44,33\0") still causes a seg fault.


    strtok is a surgical function i.e. it destroys the original string that
    it works on.
    It may not be able to change a const string.

    Check these two pieces of code:

    p1:

    int main(void) {
    char *a="something";
    a[1]='b';
    return 0;
    }

    p2:

    int main(void) {
    char a[]="something";
    a[1]='b';
    return 0;
    }

    See which one segfaults.

    --
    Ioan - Ciprian Tandau
    tandau _at_ freeshell _dot_ org (hope it's not too late)
    (... and that it still works...)
     
    Nelu, May 11, 2006
    #6
  7. Joe Smith wrote:
    > "void * clvrmnky()" <> wrote in message
    > news:KEL8g.21456$!nnrp1.uunet.ca...
    >> wrote:
    >>> I need to delimit a string. The delimiters are a semicolon and comma.
    >>> When I run the program I get a segmentation fault on the first strtok.
    >>> I followed the examples of others and from my old C books, but I can't
    >>> seem to find the problem. The accesslist has a format of
    >>> 20,45;22,44;46,28;99,43,etc. What am I doing wrong?
    >>> Thanks,
    >>>
    >>> #include <sys/signal.h>
    >>>
    >>> #include <messages.h>
    >>> #include <stdio.h>
    >>> #include <string.h>
    >>> #include <stdlib.h>
    >>> #include <unistd.h>
    >>> #include <ctype.h>
    >>>
    >>> #define or ||
    >>> #define and &&
    >>>
    >>> int createvarible(const int sock, char *name, char *type, char *value,
    >>> char *list)
    >>> {
    >>> int n=0, size, returnval=0;
    >>> char *tokenptr=NULL, *tokenptr2=NULL;
    >>> int accesscode, portnum;
    >>>
    >>> tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?
    >>>

    >> Is list non-null when first used as an arg to strtok()? Is it
    >> null-terminated?

    >
    > Non Standard stuff. Could this question have been framed so as to be
    > topical in clc? Joe
    >

    strtok() is part of string.h. Its behaviour is undefined if called
    immediately with NULL (i.e., no valid string used first to prime the
    internal objects it uses on subsequent calls).

    This is regardless of how "standard" the rest of the code is.
     
    void * clvrmnky(), May 11, 2006
    #7
  8. Guest

    I understand strtok seg faulting if the FIRST call is with NULL, but in
    my case the first call is not NULL. It is
    tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?
    list is a varible passed to the function.

    Thanks,
     
    , May 11, 2006
    #8
  9. Default User Guest

    wrote:

    Posted elsewhere:

    Here is how I call createvarible:
    createvarible(ss, "xyz", "string", "this is a test",
    "22,43;44,33")

    > I understand strtok seg faulting if the FIRST call is with NULL, but
    > in my case the first call is not NULL. It is
    > tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?
    > list is a varible passed to the function.


    You are passing a string literal as the list parameter, which you then
    send to strtok(). This causes undefined behavior.

    Also, read the information below.



    Brian
    --
    Please quote enough of the previous message for context. To do so from
    Google, click "show options" and use the Reply shown in the expanded
    header.
     
    Default User, May 11, 2006
    #9
  10. CBFalconer Guest

    wrote:
    >
    > Here is how I call createvarible:
    > createvarible(ss, "xyz", "string", "this is a test",
    > "22,43;44,33")
    > So to answer your question the string is null terminated. To null
    > terminate the string I think I have to put \0 at the end right?


    Why are you making intelligent commentary virtually impossible by
    not including adequate context? See my sig below, even on the
    impossible google interface to usenet. Read the referenced URLs
    before posting again.

    I vaguely remember you were passing some of those parameters to
    strtok. strtok modifies the string on which it operates. The
    strings you pass above are not modifiable, and any attempt to do so
    results in undefined behaviour.

    You could search the archives of this group for my "toksplit"
    function, which does not have these problems, and could be launched
    in that manner. If you reply (in the newsgroup) in the appropriate
    format I could even be persuaded to republish it.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
     
    CBFalconer, May 11, 2006
    #10
  11. Guest

    > > I understand strtok seg faulting if the FIRST call is with NULL, but
    > > in my case the first call is not NULL. It is
    > > tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?
    > > list is a varible passed to the function.

    >
    > You are passing a string literal as the list parameter, which you then
    > send to strtok(). This causes undefined behavior.
    >

    So?? I tried strtok(*list, ";"); and it still seg faults. According
    to my old C book strtok is supposed to take a string for the first
    argument. I even tried changing createvarible to:
    int createvarible(const int sock, char *varname, char *vartype, char
    *initialvalue, char accesslist[64])
    and I still get a seg fault. How can I get this thing to work.
     
    , May 12, 2006
    #11
  12. Default User Guest

    wrote:

    > > > I understand strtok seg faulting if the FIRST call is with NULL,
    > > > but in my case the first call is not NULL. It is
    > > > tokenptr = strtok(list, ";"); //this line causes the seg fault
    > > > WHY? list is a varible passed to the function.

    > >
    > > You are passing a string literal as the list parameter, which you
    > > then send to strtok(). This causes undefined behavior.
    > >

    > So?? I tried strtok(*list, ";"); and it still seg faults.


    What are you talking about? Do you know what a string literal is? You
    can't pass anything that looks like "some text" to a function that will
    modify it. You passed a string literal as the list parameter. You can't
    do that.


    Brian

    --
    Please quote enough of the previous message for context. To do so from
    Google, click "show options" and use the Reply shown in the expanded
    header.
     
    Default User, May 12, 2006
    #12
  13. Guest

    I fixed it myself. It may not be pretty but it works. I changed
    createvarible back to passing a pointer. I created a local varible
    char string[64], and did a strncpy(string,list,64) and did the strtok
    on string. All I can say strtok needs some improvements.
     
    , May 12, 2006
    #13
  14. pete Guest

    wrote:
    >
    > > > I understand strtok seg faulting if the FIRST call is with NULL,


    > > You are passing a string literal as the list parameter,
    > > which you then
    > > send to strtok(). This causes undefined behavior.
    > >

    > So?? I tried strtok(*list, ";"); and it still seg faults. According
    > to my old C book strtok is supposed to take a string for the first
    > argument.


    So, there's more involved here than just the rules for strtok.
    There's also the rules for strings.
    Attempting to modify a string literal is undefined.
    Seg fault is a blatant form of undefined behavior.

    --
    pete
     
    pete, May 12, 2006
    #14
  15. Default User Guest

    wrote:

    > I fixed it myself. It may not be pretty but it works. I changed
    > createvarible back to passing a pointer. I created a local varible
    > char string[64], and did a strncpy(string,list,64) and did the strtok
    > on string.


    Which is what I was trying to tell you.



    Brian
    --
    Please quote enough of the previous message for context. To do so from
    Google, click "show options" and use the Reply shown in the expanded
    header.
     
    Default User, May 12, 2006
    #15
  16. Jack Klein Guest

    On 11 May 2006 12:54:32 -0700, "Nelu" <> wrote in
    comp.lang.c:

    >
    > wrote:
    > > Changing the function call to createvarible(ss, "xyz", "string", "this
    > > is a test",
    > > "22,43;44,33\0") still causes a seg fault.

    >
    > strtok is a surgical function i.e. it destroys the original string that
    > it works on.
    > It may not be able to change a const string.


    Your last statement is correct, but has nothing directly to do with
    the OP's problem.

    String literals in C have the type "array of char", and very
    specifically do not have the type "array of constant char".

    Attempting to modify a string literal in C produces undefined behavior
    because the C standard specifically says so, not because, as you
    incorrectly think, they are const qualified.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, May 12, 2006
    #16
  17. Nelu Guest

    Jack Klein wrote:
    > On 11 May 2006 12:54:32 -0700, "Nelu" <> wrote in
    > comp.lang.c:
    >
    > >
    > > wrote:
    > > > Changing the function call to createvarible(ss, "xyz", "string", "this
    > > > is a test",
    > > > "22,43;44,33\0") still causes a seg fault.

    > >
    > > strtok is a surgical function i.e. it destroys the original string that
    > > it works on.
    > > It may not be able to change a const string.

    >
    > Your last statement is correct, but has nothing directly to do with
    > the OP's problem.

    That's why it crashes at the first call to strtok.

    >
    > String literals in C have the type "array of char", and very
    > specifically do not have the type "array of constant char".
    >
    > Attempting to modify a string literal in C produces undefined behavior
    > because the C standard specifically says so, not because, as you
    > incorrectly think, they are const qualified.

    Yes. The problem was that I couldn't remember 'string literal'. I guess
    I was wrong
    trying to replace it with const string. Sorry, about that.

    --
    Ioan - Ciprian Tandau
    tandau _at_ freeshell _dot_ org (hope it's not too late)
    (... and that it still works...)
     
    Nelu, May 12, 2006
    #17
  18. wrote:
    >>> I understand strtok seg faulting if the FIRST call is with NULL, but
    >>> in my case the first call is not NULL. It is
    >>> tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?
    >>> list is a varible passed to the function.

    >> You are passing a string literal as the list parameter, which you then
    >> send to strtok(). This causes undefined behavior.
    >>

    > So?? I tried strtok(*list, ";"); and it still seg faults. According
    > to my old C book strtok is supposed to take a string for the first
    > argument. I even tried changing createvarible to:
    > int createvarible(const int sock, char *varname, char *vartype, char
    > *initialvalue, char accesslist[64])
    > and I still get a seg fault. How can I get this thing to work.
    >

    Think:

    char *strtok(char *s1, const char *s2);

    The string [s1] passed to strtok() must be mutable, because it is a
    destructive function. Your appear to be passing the function a static
    buffer or literal string.

    Slow down a bit and re-read all the comments posted so far.

    Consider:

    [...]
    char *fnord = "Fnord Motor Company";
    fnord[0] = 'f'; /* Undefined behaviour */
    [...]

    Can you legally modify fnord, even with a direct assignment? If not,
    what about a library function like strtok()?
     
    void * clvrmnky(), May 12, 2006
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    1,172
  2. Bryan
    Replies:
    9
    Views:
    628
    Juha Nieminen
    Nov 1, 2007
  3. krista
    Replies:
    5
    Views:
    569
    Jim Langston
    Jan 24, 2008
  4. Replies:
    4
    Views:
    1,691
    Beej Jorgensen
    Aug 4, 2009
  5. nw
    Replies:
    7
    Views:
    878
Loading...

Share This Page