使用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
相关产品推荐
相关产品推荐

