在 C 中 strtok 段故障之后的 strcpy .


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"((。

最新更新