【问题标题】:Why does this strtok() fail when invoked with correct parameter types?为什么使用正确的参数类型调用此 strtok() 会失败?
【发布时间】:2015-08-13 16:46:06
【问题描述】:

我在我的 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(&amp;str, split)) 似乎确实可以正常工作。

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

【问题讨论】:

标签: c arrays string pointers strtok


【解决方案1】:

如果发生

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

您正在使用(指向)字符串字面量 作为第一个参数。由于strtok() 可能会尝试更改传递给它的第一个参数的内容,您将面对undefined behaviour

引用man page

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2011-04-16
    • 2012-08-21
    • 1970-01-01
    • 2017-09-18
    • 2012-07-25
    • 1970-01-01
    • 2017-08-30
    • 2022-01-07
    • 1970-01-01
    相关资源
    最近更新 更多