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

strtok_r引发segmentation fault,CSV解析代码为何出现该问题?

为什么嵌套使用strtok会导致Segmentation Fault?

嘿,我太懂这种明明代码看着和别人的差不多,却突然崩段错误的崩溃感了!问题的根源就在strtok这个函数本身的设计上——它不是线程安全的,也不支持嵌套调用,因为它内部依赖一个静态变量来保存当前的分割上下文。

咱们来拆解一下为什么会出问题:

  • 当你第一次调用strtok时,它会初始化那个静态变量,指向你要分割的字符串起始位置。
  • 后续调用strtok(NULL, delimiter)时,它会用这个静态变量来找到下一个分割点。
  • 但如果在这中间,你又调用了一次strtok(比如内层分割CSV字段),这个静态变量就会被覆盖,指向内层字符串的位置。
  • 等你回到外层继续调用strtok(NULL, ...)时,它会从被内层修改过的上下文开始处理,这时候要么访问到了已经超出原字符串范围的内存,要么指向了已经被释放/修改的内存区域,直接触发段错误。

举个典型的错误场景:

// 错误示例:嵌套strtok处理CSV
char line[] = "a,b,c;d,e,f";
char* outer_token = strtok(line, ";");
while (outer_token != NULL) {
    char* inner_token = strtok(outer_token, ","); // 这里覆盖了strtok的静态上下文
    while (inner_token != NULL) {
        printf("%s\n", inner_token);
        inner_token = strtok(NULL, ",");
    }
    outer_token = strtok(NULL, ";"); // 这里的上下文已经被内层破坏,会出问题!
}

解决办法

要避免这个问题,你有两个靠谱的选择:

  1. 使用可重入版本的strtok:
    • POSIX系统用strtok_r,它需要你自己传递一个char**类型的指针来保存上下文,内外层用不同的变量,互不干扰:
      char line[] = "a,b,c;d,e,f";
      char* outer_saveptr;
      char* outer_token = strtok_r(line, ";", &outer_saveptr);
      while (outer_token != NULL) {
          char* inner_saveptr;
          char* inner_token = strtok_r(outer_token, ",", &inner_saveptr);
          while (inner_token != NULL) {
              printf("%s\n", inner_token);
              inner_token = strtok_r(NULL, ",", &inner_saveptr);
          }
          outer_token = strtok_r(NULL, ";", &outer_saveptr);
      }
      
    • Windows系统可以用strtok_s,原理类似,只是参数顺序略有不同。
  2. 手动分割字符串:
    放弃使用strtok,改用strchr、strstr等函数手动定位分隔符,自己管理分割位置,完全避开静态变量的坑。

内容的提问来源于stack exchange,提问作者Kumar Roshan Mehta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:22:55