0
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?

J. hs
  • 11
  • 2
    What do you think `cpy` points at to make it deserving of the target of a `strcpy` ? one of countless related duplicates [can be seen here](https://stackoverflow.com/questions/22885961/getting-segmentation-fault-strcpy). – WhozCraig Apr 01 '16 at 18:45
  • 2
    You cannot copy a string to a `NULL` pointer, as in `char* cpy=NULL; ... strcpy(cpy,save);`. Segfault. – Weather Vane Apr 01 '16 at 18:45
  • Predictable..................:( – Martin James Apr 01 '16 at 18:47
  • strcpy doesn't allocate memory for you. you need to have the destination of strcpy be already allocated memory locations. – bruceg Apr 01 '16 at 18:58
  • when calling `strtok()`, Always check (!=NULL) the returned value before using that returned value for anything. – user3629249 Apr 02 '16 at 19:40
  • suggest using `strdup()` rather than `strcpy()`. Strongly suggest reading/understanding the man pages for the system functions that you call. The posted code clearly shows that certain details (described in the man pages) were not understood – user3629249 Apr 02 '16 at 19:43

5 Answers5

1

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, e.g.:

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.

Logicrat
  • 4,438
  • 16
  • 22
1

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);
rpy
  • 3,953
  • 2
  • 20
  • 31
0

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

Shiv
  • 122
  • 2
  • 16
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

Community
  • 1
  • 1
abelenky
  • 63,815
  • 23
  • 109
  • 159
0

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.

AJJ
  • 143
  • 11