C 使用strtok\u r时指针无效
运行我的代码(如第一个代码块所示)时,出现以下错误: “./a.out”中出现错误:free():无效指针:0x0000000001e4c016*** 我找到了一个修复程序(如第二个代码块所示),但我不明白为什么会发生错误 我阅读了关于strtok_r的文档,但我不明白为什么将“str”指定给一个新字符*可以解决这个问题 “rest=str”不是意味着rest和str指向同一个内存块吗。这是如何解决问题的 破译代码:C 使用strtok\u r时指针无效,c,dynamic-memory-allocation,free,c-strings,strtok,C,Dynamic Memory Allocation,Free,C Strings,Strtok,运行我的代码(如第一个代码块所示)时,出现以下错误: “./a.out”中出现错误:free():无效指针:0x0000000001e4c016*** 我找到了一个修复程序(如第二个代码块所示),但我不明白为什么会发生错误 我阅读了关于strtok_r的文档,但我不明白为什么将“str”指定给一个新字符*可以解决这个问题 “rest=str”不是意味着rest和str指向同一个内存块吗。这是如何解决问题的 破译代码: #include <stdio.h> #include <
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char* str = (char*) malloc(sizeof(char) * 128);
char* token;
printf("Enter something: ");
fgets(str, 128, stdin);
while ((token = strtok_r(str, " ", &str))) {
printf("%s\n", token);
}
free(str);
return (0);
}
#包括
#包括
#包括
int main()
{
char*str=(char*)malloc(sizeof(char)*128);
字符*令牌;
printf(“输入某物:”);
fgets(str,128,stdin);
而((token=strtok_r(str,“,&str)){
printf(“%s\n”,标记);
}
自由基(str);
返回(0);
}
固定代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char* str = (char*) malloc(sizeof(char) * 128);
char* token;
char* rest = str;
printf("Enter something: ");
fgets(str, 128, stdin);
while ((token = strtok_r(rest, " ", &rest))) {
printf("%s\n", token);
}
free(str);
return (0);
}
#包括
#包括
#包括
int main()
{
char*str=(char*)malloc(sizeof(char)*128);
字符*令牌;
char*rest=str;
printf(“输入某物:”);
fgets(str,128,stdin);
而((token=strtok_r(rest,“,&rest)){
printf(“%s\n”,标记);
}
自由基(str);
返回(0);
}
显然,调用strtok\u r
会更改指针str
,该指针作为第三个参数通过引用传递给调用
while ((token = strtok_r(str, " ", &str))) {
^^^^
printf("%s\n", token);
}
因此,在调用函数后,指针str
可以指向原始字符串内部。因此,它不会存储调用malloc
后的值
因此,使用辅助变量rest可以将初始值保留在指针str
中
请注意,您没有正确调用该函数。下面是它的描述
在第一次调用strtok_r()
时,str
应指向要调用的字符串
解析,并忽略saveptr
的值。在随后的调用中,str
应为NULL
,saveptr
自上一个
打电话
因此,对于函数的第二次和后续调用,第一个参数应为
NULL
。显然,调用strtok\r
会更改指针str
,该指针作为第三个参数通过引用传递给调用
while ((token = strtok_r(str, " ", &str))) {
^^^^
printf("%s\n", token);
}
因此,在调用函数后,指针str
可以指向原始字符串内部。因此,它不会存储调用malloc
后的值
因此,使用辅助变量rest可以将初始值保留在指针str
中
请注意,您没有正确调用该函数。下面是它的描述
在第一次调用strtok_r()
时,str
应指向要调用的字符串
解析,并忽略saveptr
的值。在随后的调用中,str
应为NULL
,saveptr
自上一个
打电话
因此,对于函数的第二次和后续调用,第一个参数应为NULL
,您应该编写:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char str[128];
char *token;
char *rest = str;
printf("Enter something: ");
fgets(str, sizeof str, stdin);
for (token = strtok_r(rest, " ", &rest);
token = strtok_r(NULL, " ", &rest);
/* just nothing here */)
{
printf("%s\n", token);
}
return (0);
}
#包括
#包括
#包括
int main()
{
char-str[128];
字符*令牌;
char*rest=str;
printf(“输入某物:”);
fgets(str,str的大小,stdin);
for(token=strtok_r(rest),“,&rest);
令牌=strtok_r(NULL,“,&rest);
/*这里什么都没有*/)
{
printf(“%s\n”,标记);
}
返回(0);
}
- 首先,您不需要为
分配内存,因为您可以定义一个本地数组来存储数据。您可以使用str
操作符,这样,如果您决定更改sizeof
的大小,您就不会冒两处不更新的风险。在使用str
的情况下,最好malloc
#定义一个常量来保存该值,同时在使用分配的缓冲区大小的任何地方使用该常量
- 其次,never强制转换
的返回值。相信我,这是一个非常坏的习惯。当您执行强制转换时,您会告诉编译器您知道自己在做什么。铸造malloc
的值是C语言中没有malloc
类型时遗留下来的(直到80年代中期)。很久以前,void
用于返回一个malloc()
,它通常不是您想要的指针类型,您必须强制转换指针以匹配您正在使用的指针。不建议在2021年强制转换char*
返回值,但强烈建议不要这样做,因为许多错误都来自于强制转换(当你做了一些不好的事情时,编译器会警告你,但如果你抛出这个值,它不会警告你,通常这会被解释为你告诉编译器你是故意做了一些奇怪的事情,因此编译器会闭嘴,不再多说)malloc()
- 第三,如果要提取字符串中的所有令牌,第一次需要调用
(或他的朋友strtok()
)当第一个参数指向字符串的开头时,但是其余的调用必须使用strtok\u w
作为第一个参数,否则您将在刚刚返回的字符串中搜索,而不是在第一次出现之后。您的问题不是使用NULL
或strtok
,因为strtok\r
只是strtok\u r
的可重入版本,它允许您在第一个线程内启动嵌套循环,或者从不同线程调用它strtok
- 你应该写:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char str[128];
char *token;
char *rest = str;
printf("Enter something: ");
fgets(str, sizeof str, stdin);
for (token = strtok_r(rest, " ", &rest);
token = strtok_r(NULL, " ", &rest);
/* just nothing here */)
{
printf("%s\n", token);
}
return (0);
}
#包括
#包括
#包括
int main()
{
char-str[128];
字符*令牌;
char*rest=str;
printf(“输入某物:”);
fgets(str,str的大小,stdin);
对于(令牌=strtok)_