如何解决system("clear")与strtok/strtok_r函数的段错误问题
解决strtok_r引发的Segmentation Fault问题
核心原因
strtok_r(包括strtok)的工作逻辑是直接修改传入的源字符串——它会把分隔符替换成\0来分割出目标片段。如果你的EXPRESSION是字符串常量(比如char *EXPRESSION = "1 + 2 * 3";),这类字符串存储在程序的只读数据段,强行修改会触发段错误。
直接解决方案(无需重写strtok)
1. 确保源字符串可写
把只读的字符串常量换成可写的字符数组,或者先将常量字符串拷贝到可写内存中:
// 错误示例:只读字符串常量 char *EXPRESSION = "3 + 4 * 2"; // 正确写法1:用字符数组存储(栈上可写) char EXPRESSION[] = "3 + 4 * 2"; // 正确写法2:如果EXPRESSION是外部传入的只读指针,先拷贝到堆内存 char *expr_copy = malloc(strlen(EXPRESSION) + 1); if (expr_copy == NULL) { perror("malloc failed"); exit(EXIT_FAILURE); } strcpy(expr_copy, EXPRESSION);
2. 正确初始化strtok_r的上下文变量
strtok_r的第三个参数(context)必须初始化为NULL,否则会导致野指针访问:
char *context = NULL; // 必须初始化 char *ptr = strtok_r(expr_copy, " \n", &context); // 循环提取所有片段 while (ptr != NULL) { printf("提取到片段:%s\n", ptr); // 后续调用传入NULL,使用context继续分割 ptr = strtok_r(NULL, " \n", &context); } // 如果用了malloc,记得释放内存 free(expr_copy);
你试过的其他方法问题分析
- strtok:和
strtok_r本质逻辑一致,同样不能处理只读字符串,且线程不安全,解决思路和上面一致。 - argc/argv:命令行传入的
argv字符串也是只读的,直接用strtok处理会触发同样的段错误,需要先拷贝到可写内存。 - 自定义函数栈溢出:大概率是数组越界、递归深度超限或者指针操作不当导致的,不过当前优先解决
strtok_r的问题即可。
完整可运行示例
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { // 模拟你的表达式(这里用可写数组) char EXPRESSION[] = "10 / 2 + 3 * 5"; char *context = NULL; char *ptr = strtok_r(EXPRESSION, " \n", &context); while (ptr != NULL) { printf("Token: %s\n", ptr); ptr = strtok_r(NULL, " \n", &context); } // 刷新终端(这里用fflush测试,不会触发段错误) printf("\n刷新终端显示\n"); fflush(stdout); return 0; }
内容的提问来源于stack exchange,提问作者totorito
相关产品推荐
相关产品推荐

