char test[10]="ab cd";
char* save=NULL;
save = strtok(test," ");
printf("%sn",save);
结果 : AB
首先,上面的代码运行良好。
接下来,我尝试执行此代码。 但是,段错误发生。
char test[10]="ab cd";
char* save=NULL;
char* cpy=NULL;
save = strtok(test," ");
strcpy(cpy,save);
printf("%sn",cpy);
我知道 strtok(( 返回只读 *char 类型。但是,我想,"保存"仅用于复制的对象。
为什么 strcpy(( 通过获取"保存"作为参数来产生分段错误?
复制到它指向的位置时,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("%sn",cpy);
导致问题的不是strtok()
,而是地址 0 的strcpy()
。
您的char *cpy
未引用任何已分配的内存。(您已将其初始化为 NULL
。所以当你调用strcpy(cpy,save)
时,你正在写入一个空指针。
您可能希望先分配内存:
cpy = malloc(strlen(save)+1);
strcyp(cpy,save);
strcpy
在这种情况下,您必须首先为"cpy"分配内存,以便将"save"复制到"cpy"。这里的"保存"工作正常strtok
因为只有返回成功的指针......这就是为什么您不需要为"保存"分配内存的原因。并且您正在通过保存传递地址,所以没关系..所以总体上首先为"cpy"分配内存,以便strcpy
可以将"保存"复制到"cpy"中。
使用 strdup
save = strtok(test," ");
cpy = strdup(save);
printf("%sn",cpy);
free(cpy);
完成后不要忘记释放内存。
另请阅读此内容
如前所述,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 = ‘ ’;
else
strcpy(dest, getenv(“NOTHING”));
因此,我创建了一个 strcpy_w(( 包装器,它将 NULL src 参数视为与 *src 为 '\0' 一样。我对其他字符串函数做了同样的事情,也检查缓冲区溢出。然后,我只需要添加以下内容即可始终使用包装器:
#define strcpy(x, y) strcpy_w(x, y)
或者我可以叫strcpy_w(dest, getenv("NOTHING"((。