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

如何解决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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:55:12