Since oldstr is just a pointer, assignment will not create a new copy of your string.
Copy it before passing str to strtok :
char *oldstr=malloc(sizeof(str)); strcpy(oldstr,str);
Your patched version:
#include <stdio.h> #include <string.h> #include<malloc.h> int main (void) { char str[] = "John|Doe|Melbourne|6270|AU"; char fname[32], lname[32], city[32], zip[32], country[32]; char *oldstr = malloc(sizeof(str)); strcpy(oldstr,str); ................... free(oldstr); return 0; }
EDIT:
As mentioned in @CodeClown, in your case it is better to use strncpy . And instead of manually fixing the sizes of fname , etc., you can have pointers in place and allocate memory, as required, no more and no less. This way you can avoid writing to the buffer outside the bounds.
Another idea: it would assign the result of strtok the *fname , *lname , etc. instead of arrays. It seems that strtok intended to be used this way after looking at the accepted answer.
Caution: this way, if you change str further, that will be reflected in fname , lname . Because they simply point to str data, but not to new blocks of memory. So use oldstr for other manipulations.
#include <stdio.h> #include <string.h> #include<malloc.h> int main (void) { char str[] = "John|Doe|Melbourne|6270|AU"; char *fname, *lname, *city, *zip, *country; char *oldstr = malloc(sizeof(str)); strcpy(oldstr,str); fname=strtok(str,"|"); lname=strtok(NULL,"|"); city=strtok(NULL, "|"); zip=strtok(NULL, "|"); country=strtok(NULL, "|"); printf("Firstname: %s\n", fname); printf("Lastname: %s\n", lname); printf("City: %s\n", city); printf("Zip: %s\n", zip); printf("Country: %s\n", country); printf("STR: %s\n", str); printf("OLDSTR: %s\n", oldstr); free(oldstr); return 0; }