strtok()在C99中返回错误的值?

时间:2016-04-06 00:40:27

标签: c pointers valgrind c99

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

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

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

2 个答案:

答案 0 :(得分:3)

下面:

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()返回到它的内容,然后推送它们。

答案 1 :(得分:0)

我知道这已经回答了,但是由于这个原因,我建议在for()而不是while()中使用strtok,因为它实际上有一个初始化器,测试条件和迭代器。例如:

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