为什么在使用正确的参数类型调用时此 strtok() 会失败?
Why does this strtok() fail when invoked with correct parameter types?
我已将我的 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
的指针的原始实现失败并抛出总线错误。
如果
char* str = "www.example.com";
/// some code
tok = strtok(str, split);
您正在使用(指向)字符串文字 作为第一个参数。由于 strtok()
可能会尝试更改传递给它的第一个参数的内容,您将面临 undefined behaviour.
引用自man page
Be cautious when using these functions. If you do use them, note that:
These functions modify their first argument. [...]
关于尝试更改字符串文字,来自 C11
,章节 §6.4.5
[...] If the program attempts to modify such an array, the behavior is
undefined
OTOH,如果你创建一个数组,用字符串文字初始化它并将数组传递给 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
的指针的原始实现失败并抛出总线错误。
如果
char* str = "www.example.com";
/// some code
tok = strtok(str, split);
您正在使用(指向)字符串文字 作为第一个参数。由于 strtok()
可能会尝试更改传递给它的第一个参数的内容,您将面临 undefined behaviour.
引用自man page
Be cautious when using these functions. If you do use them, note that:
These functions modify their first argument. [...]
关于尝试更改字符串文字,来自 C11
,章节 §6.4.5
[...] If the program attempts to modify such an array, the behavior is undefined
OTOH,如果你创建一个数组,用字符串文字初始化它并将数组传递给 strtok()
,这是非常好的,因为你的数组可以被你的程序修改。