简体   繁体   中英

strcpy after strtok segmentfault in C

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

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

result : 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. but, i guess, 'save' is used only copied object.

it is not change. why strcpy() makes segmentfault error by get 'save' as parameter?

Your char *cpy is not referencing any allocated memory. (You initialized it to NULL . So when you call strcpy(cpy,save) , you are writing to a NULL-pointer.

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". 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".

cpy is explicitly NULL when you copy into the location it's pointing to. 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:

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.

Use 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. 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:

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

Either strtok() or getenv() could return a NULl, which is passed to strcpy() causing a segfault. I didn't want to put a lot of NULL checking into my code, like:

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'. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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