繁体   English   中英

C中的strtok segmentfault后的strcpy

[英]strcpy after strtok segmentfault in C

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'作为参数使segmentfault错误?

您的char *cpy没有引用任何已分配的内存。 (将其初始化为NULL 。因此,当您调用strcpy(cpy,save) ,您正在写入NULL指针。

您可能要先分配内存:

cpy = malloc(strlen(save)+1);
strcyp(cpy,save);

strcpy情况下,您必须首先为“ cpy”分配内存,以便可以将“保存”复制到“ cpy”。 这里的“保存”工作正常,因为strtok仅在成功时返回指针...这就是为什么您不需要为“保存”分配内存。并且您通过保存传递地址因此就可以了。为“ cpy”,以便strcpy可以将“保存”复制到“ cpy”中。

当您将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。

使用strdup

save = strtok(test," ");
cpy = strdup(save);
printf("%s\n",cpy);
free(cpy);

完成操作后,不要忘记释放内存。

请阅读

如前所述,strcpy()和大多数字符串例程一样,如果传递NULL参数,则将出现段错误。 这适用于src和dest args(至少在旧版本的glibc中),这使得无法执行以下简单操作:

strcpy(dest, strtok(NULL, “ “));
strcpy(dest, getenv(“NOTHNG”);

strtok()或getenv()都可以返回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”))。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM