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'作为参数来产生段错误?
你的char *cpy
没有引用任何分配的内存。 (你把它初始化为NULL
。所以当你调用strcpy(cpy,save)
时,你正在写一个NULL指针。
您可能希望先分配内存:
cpy = malloc(strlen(save)+1);
strcyp(cpy,save);
在strcpy
的情况下,你必须首先为“cpy”分配内存,以便“save”可以复制到“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。
如前所述,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”))。