strtok_r上的分段错误

时间:2018-04-07 15:16:42

标签: c segmentation-fault strtok

    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行产生分段错误,我无法弄清楚原因。 缓冲区看起来像“雇佣军2位置15 20”。 任何人都可以帮助我吗?

3 个答案:

答案 0 :(得分:0)

  

strtok_r,如果找到一个标记,则指向标记开头的指针。   否则,空指针。当。时总是返回空指针   字符串中的字符串结尾(即空字符)   被扫描。

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不会在字符串的末尾放置一个空终结符(而printf %s假设有一个)。

答案 1 :(得分:0)

有一些地方可能会出错 - 我们不能只告诉你哪些是错的。

recv()返回" 接收的字节数,如果发生错误则返回-1 " - 你无法知道这里是否出现问题(除非你检查返回值)。此外,recv()不会终止" 字符串",因为只要它知道/关心,它只是数据。

sprintf()会写入缓冲区而不管它有多长时间 - 除非你能保证有足够的空间,否则不要使用它。使用snprintf()代替缓冲区的长度。另外,检查潜在问题的返回值。但是,500 x char的缓冲区看起来确实非常大。

我很高兴看到您使用的是strtok_r(),而不是strtok()。您使用它的方法不对,但根据this unrelated Linux (not C) reference,您的使用不应该导致问题

  

在第一次调用strtok_r()时,str应指向要解析的字符串,并忽略saveptr的值。 在后续调用中,str应为NULL ,并且saveptr应自上次调用后保持不变。

     

strtok()strtok_r()函数返回指向下一个标记的指针,如果没有其他标记则返回NULL。

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

  1. token为NULL
  2. token未终止,因此printf()正在进入杂草。
  3. 我会在#1上下注,因为你应该在第一个printf("\n%s\n", buffer);看到了一个SEGFAULT。我说" 应该"因为你可能很幸运 - 打印" 看不见"在这一点上垃圾。

答案 2 :(得分:0)

我真的不知道出了什么问题。我试过在另一个IDE中运行了。 感谢您的帮助。