简体   繁体   中英

Segmentation fault on strtok_r

    char buffer[1000];
    recv(sock, buffer, sizeof(buffer), 0);
    char *ptr;
    printf("\n%s\n", buffer);
    char searchPos[500];
    sprintf(searchPos, "mercenary %d position", ID);
    char *req = strstr(buffer, searchPos);
    if(req != NULL)
    {
        char *token;
        token = strtok_r(buffer, " ", &ptr);
        token = strtok_r(ptr, " ", &ptr);
        token = strtok_r(ptr, " ", &ptr);
        token = strtok_r(ptr, " ", &ptr);
        printf("%s\n",token);
    }

I have this code that produce a segmentation fault at the printf line and I can't figure out why. buffer looks like "mercenary 2 position 15 20". Can anyone help me ?

strtok_r, if a token is found, a pointer to the beginning of the token. Otherwise, a null pointer . A null pointer is always returned when the end of the string (ie, a null character) is reached in the string being scanned.

char buffer[1000];

// make sure all bytes are initialized to 0
memset(buffer, '\0', sizeof(buffer)); 
// make sure there is at least one byte left that's set to 0
if( recv(sock, buffer, sizeof(buffer) - 1, 0) == -1 ) {
    perror("recv()");
    exit(1);
}

recv does not place a null terminator at the end of the string (whilst printf %s assumes there is one).

There are a handful of places that this could be going wrong - we cannot just tell you what's wrong.

recv() returns " the number of bytes received, or -1 if an error occured " - you have no way of knowing if things went wrong here (unless you check the return value). Additionally, recv() will not nul terminate the " string ", because as far as it knows / cares, it's just data.

sprintf() will write to the buffer with no regard to how long it is - don't use it unless you can guarantee there's sufficient space. Use snprintf() instead which will respect the length of the buffer. Also, check the return value for potential problems. Your buffer of 500x char does appear to be exceedingly large, however.

I'm pleased to see you are using strtok_r() , and not strtok() . You're using it wrong, but your use shouldn't really cause a problem per-se, according to this unrelated Linux (not C) reference .

On the first call to strtok_r() , str should point to the string to be parsed, and the value of saveptr is ignored. In subsequent calls, str should be NULL , and saveptr should be unchanged since the previous call.

The strtok() and strtok_r() functions return a pointer to the next token, or NULL if there are no more tokens .

Finally, printf() is probably causing a SEGFAULT due to one of these problems:

  1. token is NULL
  2. token is not nul terminated, and thus printf() is running into the weeds.

I'd place bets on #1, as you should have seen a SEGFAULT at the first printf("\\n%s\\n", buffer); otherwise. I say " should " because you may be lucky - printing " invisible " garbage at this point.

I really don't know what was wrong. I tried in another IDE and it worked. Thank's for the help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM