You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用strtok_r时触发Segmentation fault问题排查求助

分析与修复你的段错误问题

让我帮你拆解下这段代码里触发Segmentation fault的核心原因,以及对应的修复方案:

1. 未处理recv返回的无终止符缓冲区

recv函数只会将接收到的字节写入buffer,不会自动添加字符串终止符\0。而printf("%s", buffer)要求输入是一个以\0结尾的合法C字符串,如果没有终止符,printf会一直读取内存直到遇到随机的\0,这大概率会越界访问非法内存,直接触发段错误。

修复方式:

先捕获recv的返回值,根据返回值处理终止符和错误:

ssize_t recv_len = recv(sock, buffer, sizeof(buffer) - 1, 0); // 留一个字节给终止符
if (recv_len == -1) {
    perror("recv failed");
    return; // 或其他错误处理逻辑
} else if (recv_len == 0) {
    // 连接已关闭的情况
    return;
}
buffer[recv_len] = '\0'; // 手动添加字符串终止符

2. strtok_r调用逻辑错误+未做NULL检查

你的代码里连续调用了4次strtok_r来获取第四个字段,但存在两个致命问题:

  • 后续调用strtok_r时,第一个参数错误地传了ptr,正确写法应该是NULL(用来继续解析同一个字符串);
  • 没有检查每次strtok_r的返回值,如果buffer里的空格分隔字段不足4个,后续调用会返回NULL,直接printf("%s", token)就相当于访问NULL指针,必然触发段错误。

修复方式:

修正strtok_r的调用逻辑,并添加NULL检查:

char *token;
token = strtok_r(buffer, " ", &ptr);
if (token == NULL) goto end_parse;
token = strtok_r(NULL, " ", &ptr);
if (token == NULL) goto end_parse;
token = strtok_r(NULL, " ", &ptr);
if (token == NULL) goto end_parse;
token = strtok_r(NULL, " ", &ptr);
if (token != NULL) {
    printf("%s\n", token);
}
end_parse: ;

3. 额外的安全优化建议

  • 修正解析逻辑:你用strstr找到了searchPos的匹配位置,但后续解析的是整个buffer,如果你的目标是从匹配位置开始解析,应该把req作为strtok_r的初始输入,而不是原始buffer;
  • 替换sprintf为snprintf:sprintf存在缓冲区溢出风险,改用snprintf可以限制写入长度,更安全:
    snprintf(searchPos, sizeof(searchPos), "mercenary %d position", ID);
    

把这些修复点整合后,你的代码应该就能避免段错误了。

内容的提问来源于stack exchange,提问作者Creends

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:47:08