简体   繁体   English

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

I have this code that produce a segmentation fault at the printf line and I can't figure out why. 我有这段代码在printf行上产生了分段错误,我不知道为什么。 buffer looks like "mercenary 2 position 15 20". 缓冲区看起来像“雇佣2位置15 20”。 Can anyone help me ? 谁能帮我 ?

strtok_r, if a token is found, a pointer to the beginning of the token. strtok_r(如果找到令牌),指向令牌开头的指针。 Otherwise, a null pointer . 否则为null指针 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). recv不会在字符串的末尾放置一个空终止符(而printf %s假定存在一个终止符)。

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). recv()返回“ 接收到的字节数,如果发生错误,则返回-1 ”-您无法知道此处是否出错(除非您检查返回值)。 Additionally, recv() will not nul terminate the " string ", because as far as it knows / cares, it's just data. 另外, recv()不会nul终止“ string ”,因为据它所知/所关心的,它只是数据。

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. sprintf()会写入缓冲区,而不管缓冲区有多长-除非可以保证有足够的空间,否则不要使用它。 Use snprintf() instead which will respect the length of the buffer. 请改用snprintf() ,它会考虑缓冲区的长度。 Also, check the return value for potential problems. 另外,检查返回值是否存在潜在问题。 Your buffer of 500x char does appear to be exceedingly large, however. 但是,您的500x char缓冲区确实看起来非常大。

I'm pleased to see you are using strtok_r() , and not strtok() . 我很高兴看到您使用的是strtok_r()而不是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 . 根据此无关的Linux(非C)参考资料 ,您使用的是错误的,但是使用它本身并不会真正引起问题

On the first call to strtok_r() , str should point to the string to be parsed, and the value of saveptr is ignored. 在第一次调用strtok_r()str应该指向要解析的字符串,而saveptr的值将被忽略。 In subsequent calls, str should be NULL , and saveptr should be unchanged since the previous call. 在后续调用中, str应该为NULL ,而自上次调用以来, saveptr应该保持不变。

The strtok() and strtok_r() functions return a pointer to the next token, or NULL if there are no more tokens . strtok()strtok_r()函数返回指向下一个标记的指针, 如果没有更多标记返回NULL

Finally, printf() is probably causing a SEGFAULT due to one of these problems: 最后,由于以下问题之一, printf()可能会导致SEGFAULT:

  1. token is NULL token为NULL
  2. token is not nul terminated, and thus printf() is running into the weeds. token没有被nul终止,因此printf()正在进入杂草。

I'd place bets on #1, as you should have seen a SEGFAULT at the first printf("\\n%s\\n", buffer); 我将赌注押在#1上,因为您应该在第一个printf("\\n%s\\n", buffer);处看到SEGFAULT 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. 我在另一个IDE中尝试过,它起作用了。 Thank's for the help. 谢谢您的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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