我首先使用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并且没有任何错误。我不知道为什么会这样,我真的可以使用一些帮助。感谢。
答案 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);
}