tags:

views:

357

answers:

4

I have a functions which takes a char * as its only argument. I then perform some strtok operations on it. Sometimes it works and sometimes it doesent. It working depends upon how the string was constructed. For instance here are the two cases.

int main()
{
   char glob[] = "/abc/def/ghi";
   char *glob2 = "/abc/def/ghi";

   func(glob);  //this one works
   func(glob2); //this one doesnt work

   return 0;
}

What is the difference between the two allocation methods and why does strtok blow up on the second one?

+6  A: 

Strtok writes to the memory allocated to the string.

You cannot write to statically allocated string memory on most compilers/runtimes/hardware. You can write to the stack.

kmarsh
+12  A: 

strtok() basically modifies the input string.

char *glob2 = "/abc/def/ghi";

In above case the glob2 points to read-only data and hence it fails, whereas with 'char glob[] = "/abc/def/ghi";' the data is not read-only, it's available in char array. Hence it allows the modifications.

aJ
Quoting from the man page:Be cautious when using these functions. If you do use them, note that: - These functions modify their first argument. - These functions cannot be used on constant strings. - The identity of the delimiting character is lost. - The strtok() function uses a static buffer while parsing, so it’s not thread safe. Use strtok_r() if this matters to you.
Cristian Ciupitu
+6  A: 

char[] str1 = "foo" allocates an array of the chars on the stack (assuming this is inside a function). That array can be modified without a problem.

const char *str = "foo" gives you a pointer to the string foo, which will usually reside in read-only memory.

char *str = "foo" will do the same thing but implicitly remove the const (without actually changing the fact that the pointer likely points to read-only memory).

sepp2k
A: 

The other comments are correct; you should use strtok_r() instead.

James Youngman
-1, since strtok_r doesn't actually relate directly to the problem here: *Both* strtok_r and strtok modify the input buffer
therefromhere
Ah yes, you're right.
James Youngman