【问题标题】:strtok() returning incorrect value in C99?strtok() 在 C99 中返回不正确的值?
【发布时间】:2016-04-06 00:40:26
【问题描述】:

我首先使用 std c99 在 32 位 linux 系统上运行。所以我有这个代码

char* tokPtr = strtok(expr, " ");
    while(tokPtr != NULL) {
            tokPtr = strtok(NULL, " ");
            puts(tokPtr);
            push(tokens, tokPtr);
    }

expr 是作为参数传入的 C 字符串,类似于“1 2 +”。而且我只是将 puts 用于测试目的。但是,当我运行带有 --leak-check=full 标志的 valgrind 时,我在 put 中读取 strlen 的大小为 1 并以 seg 错误结束。当我让 tokPtr = "1";并注释掉 strtok() 的东西,我运行 valgrind 并且完全没有错误。我不知道为什么会这样,我真的可以使用一些帮助。谢谢。

【问题讨论】:

  • 我最后的办法是循环 strtok() 并在第一部分被切断的情况下重置字符串。

标签: c pointers valgrind c99


【解决方案1】:

这里:

while(tokPtr != NULL) {
    tokPtr = strtok(NULL, " ");
    puts(tokPtr);

你应该检查tokPtr == NULL 之后你打电话给strtok(),而不是之前。当strtok() 最终返回NULL 时,您将始终使用此代码将NULL 传递给puts(),这就是您的问题。

您可以重新排序,然后更改为:

char* tokPtr = strtok(expr, " ");
while(tokPtr != NULL) {
    puts(tokPtr);
    push(tokens, tokPtr);
    tokPtr = strtok(NULL, " ");
}

还要记住strtok() 修改了它使用的字符串并返回指向该字符串的内部指针。您没有显示您的 push() 函数,但除非代码非常简单,并且您的 expr 数组总是比您的堆栈长,否则您可能会遇到将这些指针推到它上面的问题。最好为每个令牌 malloc() 分配一些内存并将 strtok() 返回的内容复制到其中,然后推送它们。

【讨论】:

  • 好的,我明白了,谢谢你的帮助,效果很好
【解决方案2】:

我知道这已经得到解答,但正是出于这个原因,我建议在 for() 中使用 strtok 而不是 while(),因为它自然有一个初始化程序、测试条件和迭代器。例如:

for( char* tokPtr = strtok(expr, " ");
     tokPtr != NULL;
     tokPtr = strtok(NULL, " ") )
{
    puts(tokPtr);
    push(tokens, tokPtr);
}

【讨论】:

  • 谢谢,这实际上是一个非常有用的例子
猜你喜欢
  • 1970-01-01
  • 2014-01-27
  • 2017-11-04
  • 2016-10-09
  • 2021-10-26
  • 2015-10-13
  • 2014-12-06
  • 2021-02-01
  • 2017-08-21
相关资源
最近更新 更多