简体   繁体   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);

result : ab 结果:ab

First, above code works very well. 首先,以上代码效果很好。

Next, I tryed to excute this code. 接下来,我尝试执行此代码。 but, segmentfault occurs. 但是,发生段故障。

char test[10]="ab cd";
char* save=NULL;
char* cpy=NULL;

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

I know strtok() returns read-only *char type. 我知道strtok()返回只读* char类型。 but, i guess, 'save' is used only copied object. 但是,我想,“保存”仅用于复制的对象。

it is not change. 它没有改变。 why strcpy() makes segmentfault error by get 'save' as parameter? 为什么strcpy()通过获取'save'作为参数使segmentfault错误?

Your char *cpy is not referencing any allocated memory. 您的char *cpy没有引用任何已分配的内存。 (You initialized it to NULL . So when you call strcpy(cpy,save) , you are writing to a NULL-pointer. (将其初始化为NULL 。因此,当您调用strcpy(cpy,save) ,您正在写入NULL指针。

You might want to allocate memory first: 您可能要先分配内存:

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

In strcpy case you have to first allocate memory for "cpy" so that "save" can be copied to "cpy". strcpy情况下,您必须首先为“ cpy”分配内存,以便可以将“保存”复制到“ cpy”。 Here "save" is working fine because strtok only return pointer on success...That's why you don't need to allocate memory for "save".And you are passing an address by save so it's fine..So overall first allocate memory for "cpy" so that strcpy can copy "save" into "cpy". 这里的“保存”工作正常,因为strtok仅在成功时返回指针...这就是为什么您不需要为“保存”分配内存。并且您通过保存传递地址因此就可以了。为“ cpy”,以便strcpy可以将“保存”复制到“ cpy”中。

cpy is explicitly NULL when you copy into the location it's pointing to. 当您将cpy复制到它指向的位置时,它显式为NULL。 That's guaranteed to give you a memory write error of some kind. 这样可以保证给您某种内存写入错误。

I suggest you initialize cpy to point to some memory that's actually available, eg: 我建议您初始化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);

It's not strtok() that's causing the problem, it's the strcpy() into address 0. 不是strtok()导致了问题,而是strcpy()进入了地址0。

Use strdup 使用strdup

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

Don't forget to free the memory when you're done with it. 完成操作后,不要忘记释放内存。

Also read this 请阅读

As provided earlier, strcpy() like most string routines will segfault if passed a NULL argument. 如前所述,strcpy()和大多数字符串例程一样,如果传递NULL参数,则将出现段错误。 This applies to both the src and dest args (at least in older versions of glibc), which makes it impossible to do simple things like: 这适用于src和dest args(至少在旧版本的glibc中),这使得无法执行以下简单操作:

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

Either strtok() or getenv() could return a NULl, which is passed to strcpy() causing a segfault. strtok()或getenv()都可以返回NULl,该值将传递给strcpy()导致段错误。 I didn't want to put a lot of NULL checking into my code, like: 我不想在代码中放入很多NULL检查,例如:

if (getenv(“NOTHING”) != NULL)
    *dest = ‘\0’;
else
    strcpy(dest, getenv(“NOTHING”));

So, I created a strcpy_w() wrapper that treats a NULL src argument the same as if *src is '\\0'. 因此,我创建了一个strcpy_w()包装器,将NULL src参数视为与* src为'\\ 0'相同。 I did the same for other string functions, also checking for buffer overflows. 对于其他字符串函数,我也进行了相同的操作,还检查了缓冲区溢出。 Then, I just had to add the following to always use the wrapper: 然后,我只需要添加以下内容即可始终使用包装器:

#define strcpy(x, y) strcpy_w(x, y)

Or I could call strcpy_w(dest, getenv(“NOTHING”)) instead. 或者,我可以改为调用strcpy_w(dest,getenv(“ NOTHING”))。

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

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