strtok() 在 C99 中返回不正确的值?
strtok() returning incorrect value in 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 时,它为我在 puts 中为 strlen 提供了大小为 1 的无效读取,并以段错误结束。当我让 tokPtr = "1";并注释掉 strtok() 的东西,我 运行 valgrind 完全没有错误。我不知道为什么会这样,我真的需要一些帮助。谢谢
这里:
while(tokPtr != NULL) {
tokPtr = strtok(NULL, " ");
puts(tokPtr);
你应该检查是否 tokPtr == NULL
在你调用 之后,而不是之前。当 strtok()
最终执行 return NULL
时,您将始终使用此代码将 NULL
传递给 puts()
,这就是您的问题。
您可以重新排序,然后更改为:
char* tokPtr = strtok(expr, " ");
while(tokPtr != NULL) {
puts(tokPtr);
push(tokens, tokPtr);
tokPtr = strtok(NULL, " ");
}
还要记住,strtok()
修改了它使用的字符串和 return 指向该字符串的内部指针。你没有显示你的 push()
函数,但除非代码非常简单,并且你的 expr
数组总是比你的堆栈更持久,否则你可能 运行 会遇到将这些指针推入的问题它。为每个令牌 malloc()
一些内存并将 strtok()
return 复制到其中,然后推送这些可能会更好。
我知道这已经得到解答,但正是出于这个原因,我建议在 for() 而不是 while() 中使用 strtok,因为它自然具有初始化程序、测试条件和迭代器。例如:
for( char* tokPtr = strtok(expr, " ");
tokPtr != NULL;
tokPtr = strtok(NULL, " ") )
{
puts(tokPtr);
push(tokens, tokPtr);
}
我运行正在使用 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 时,它为我在 puts 中为 strlen 提供了大小为 1 的无效读取,并以段错误结束。当我让 tokPtr = "1";并注释掉 strtok() 的东西,我 运行 valgrind 完全没有错误。我不知道为什么会这样,我真的需要一些帮助。谢谢
这里:
while(tokPtr != NULL) {
tokPtr = strtok(NULL, " ");
puts(tokPtr);
你应该检查是否 tokPtr == NULL
在你调用 之后,而不是之前。当 strtok()
最终执行 return NULL
时,您将始终使用此代码将 NULL
传递给 puts()
,这就是您的问题。
您可以重新排序,然后更改为:
char* tokPtr = strtok(expr, " ");
while(tokPtr != NULL) {
puts(tokPtr);
push(tokens, tokPtr);
tokPtr = strtok(NULL, " ");
}
还要记住,strtok()
修改了它使用的字符串和 return 指向该字符串的内部指针。你没有显示你的 push()
函数,但除非代码非常简单,并且你的 expr
数组总是比你的堆栈更持久,否则你可能 运行 会遇到将这些指针推入的问题它。为每个令牌 malloc()
一些内存并将 strtok()
return 复制到其中,然后推送这些可能会更好。
我知道这已经得到解答,但正是出于这个原因,我建议在 for() 而不是 while() 中使用 strtok,因为它自然具有初始化程序、测试条件和迭代器。例如:
for( char* tokPtr = strtok(expr, " ");
tokPtr != NULL;
tokPtr = strtok(NULL, " ") )
{
puts(tokPtr);
push(tokens, tokPtr);
}