char test[10]="ab cd";
char* save=NULL;
save = strtok(test," ");
printf("%s\n",save);
结果:ab
首先,上面的代码效果非常好。
接下来,我尝试执行此代码。但是,发生了段故障。
char test[10]="ab cd";
char* save=NULL;
char* cpy=NULL;
save = strtok(test," ");
strcpy(cpy,save);
printf("%s\n",cpy);
我知道strtok()返回只读* char类型。 但是,我猜,“保存”仅用于复制的对象。
这不是变化。为什么strcpy()通过获取'save'作为参数来产生段错误?
答案 0 :(得分:1)
您的char *cpy
未引用任何已分配的内存。 (您将其初始化为NULL
。因此,当您调用strcpy(cpy,save)
时,您正在写入NULL指针。
您可能希望先分配内存:
cpy = malloc(strlen(save)+1);
strcyp(cpy,save);
答案 1 :(得分:0)
在strcpy
案例中,您必须先为" cpy"分配内存。所以"保存"可以复制到" cpy"。在这里"保存"工作正常,因为strtok
只返回指针成功...这就是为什么你不需要为"保存"分配内存的原因。你传递的地址是保存,所以很好。所以总体上首先为" cpy"分配内存。以便strcpy
可以复制"保存"进入" cpy"。
答案 2 :(得分:0)
cpy
显式为NULL。这保证会给你一些内存写错误。
我建议你初始化cpy
以指出一些实际可用的记忆,例如:
char temp[100];
char test[10]="ab cd";
char* save=NULL;
char* cpy=temp; // Set cpy to point to temp buffer
save = strtok(test," ");
strcpy(cpy,save);
printf("%s\n",cpy);
导致问题的不是strtok()
,而是strcpy()
导致地址0。
答案 3 :(得分:0)
使用strdup
save = strtok(test," ");
cpy = strdup(save);
printf("%s\n",cpy);
free(cpy);
当你完成记忆时,不要忘记释放记忆。
答案 4 :(得分:0)
如前所述,strcpy()和大多数字符串例程一样,如果传递了NULL参数,则将出现段错误。这适用于src和dest args(至少在旧版本的glibc中),这使得无法执行以下简单操作:
strcpy(dest, strtok(NULL, “ “));
strcpy(dest, getenv(“NOTHNG”);
strtok()或getenv()都可以返回NULl,该NULl传递给strcpy()会导致段错误。我不想在代码中进行很多NULL检查,例如:
if (getenv(“NOTHING”) != NULL)
*dest = ‘\0’;
else
strcpy(dest, getenv(“NOTHING”));
因此,我创建了一个strcpy_w()包装器,该包装器将NULL src参数视为与* src为“ \ 0”相同。对于其他字符串函数,我也进行了相同的操作,还检查了缓冲区溢出。然后,我只需要添加以下内容即可始终使用包装器:
#define strcpy(x, y) strcpy_w(x, y)
或者我可以改为调用strcpy_w(dest,getenv(“ NOTHING”))。