为什么在使用正确的参数类型调用时,这个strtok()会失败?

时间:2015-08-13 16:46:07

标签: c arrays string pointers strtok

我在C程序中跟踪了一个问题strtok()(其签名,记录为char *strtok(char *str, const char *delim))。试图在一个简单的玩具程序中重新创建问题时,我遇到了障碍 - 我每次尝试运行代码时都会传递所有正确的参数类型并出现总线错误。

以下是该计划:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
     char* tok;
     char* str = "www.example.com";
     const char* split = ".";

     tok = strtok(str, split);
     while(tok != NULL) {
         printf("%s\n", tok);
         tok = strtok(NULL, split);
     }
}

奇怪的是,我发现将str声明为数组(char str[] = "www.example.com")并将对str的引用传递给最初的strtok调用(tok = strtok(&str, split))似乎工作正常。

我真的不担心这里的功能 - 使用数组的解决方案有效。我很好奇为什么使用指向char的指针的原始实现失败并引发总线错误。

1 个答案:

答案 0 :(得分:2)

如果是

 char* str = "www.example.com";
 /// some code
 tok = strtok(str, split);

您使用(指针)字符串文字作为第一个参数。由于strtok()可能会尝试更改传递给它的第一个参数的内容,因此您将面临undefined behaviour

man page

引用
  

使用这些功能时要小心。如果您确实使用它们,请注意:

     

这些函数修改了他们的第一个参数。 [...]

关于尝试更改字符串文字,来自C11,章节§6.4.5

  

[...]如果程序试图修改这样的数组,行为是   未定义

OTOH,如果你创建一个数组,用字符串文字初始化它并将数组传递给strtok(),这很好,因为你的程序可以修改你的数组。