strtok_r 上的分段错误

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);
    }

我的这段代码在 printf 行产生了一个分段错误,我不知道为什么。 缓冲区看起来像 "mercenary 2 position 15 20"。 谁能帮帮我?

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 (i.e., a null character) is reached in the string being scanned.

char buffer[1000];

// make sure all bytes are initialized to 0
memset(buffer, '[=10=]', 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 不会在字符串末尾放置空终止符(而 printf %s 假定有一个)。

有几个地方可能会出错 - 我们不能只告诉你哪里出了问题。

recv() returns “接收到的字节数,如果发生错误则为 -1” - 你无法知道事情是否发生这里出错了(除非你检查 return 值)。此外,recv() 不会 nul 终止“string”,因为据它所知/关心,它只是数据。

sprintf() 将写入缓冲区而不考虑它有多长 - 不要使用它除非你能保证有足够的 space。使用 snprintf() 代替,这将尊重缓冲区的长度。此外,检查 return 值是否存在潜在问题。但是,您的 500x char 缓冲区确实显得非常大。

很高兴看到您使用 strtok_r(),而不是 strtok()。你用错了,但根据 this unrelated Linux (not C) reference.

,你的使用不应该真正导致 问题 per-se

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.

最后,printf() 可能由于以下问题之一导致 SEGFAULT:

  1. token 为 NULL
  2. token 不是 nul 终止的,因此 printf() 是 运行 的杂草。

我会打赌 #1,否则您 应该 在第一个 printf("\n%s\n", buffer); 看到 SEGFAULT。我说“应该”是因为你可能很幸运——此时打印“invisible”垃圾。

我真的不知道哪里出了问题。我在另一个 IDE 中尝试过,它成功了。 感谢您的帮助。