4

Possible Duplicate:
Why do I get a segmentation fault when writing to a string?

I'm experiencing a strange issue with my C code. I'm trying to split string using strtok function, but I get access violation exception. Here's my code:

char *token;
char *line = "LINE TO BE SEPARATED";
char *search = " ";
token = strtok(line, search); <-- this code causes crash

However, if I change char *line to char line[], everything works as expected and I don't get any error.

Anyone can explain why I get that (strange for me) behavior with strtok? I thought char* and char[] was the same and exact type.

UPDATE

I'm using MSVC 2012 compiler.

Community
  • 1
  • 1
Davita
  • 8,928
  • 14
  • 67
  • 119

4 Answers4

8

strtok() modifies the string that it parses. If you use:

char* line = "...";

then a string literal is being modified, which is undefined behaviour. When you use:

char[] line = "...";

then a copy of the string literal is being modified.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • 1
    Correct; a quick fix is to write `char *line = strdup("LINE TO BE SEPARATED");`, but just remember to free up the memory afterwards. As a note to the poster, gcc gives a warning about this when compiling. For MSVC you should enable all warnings to catch errors like this. – csl Nov 28 '12 at 14:23
  • 1
    @csl, sound advice on warnings (`/W4` and `/WX` for VC). – hmjd Nov 28 '12 at 14:26
  • 1
    @csl - and note that `strdup` is not part of standard C or of standard C++. – Pete Becker Nov 28 '12 at 14:30
  • 1
    for `char* line = "...";` I would rather say: a read-only (or const) string literal is being modified. Just to make it more clear. – sciarp Nov 28 '12 at 14:32
  • @PeteBecker Thanks, I wasn't aware! – csl Nov 28 '12 at 14:36
  • @sciarp: `char* line = "..."` is not `const` though. Declaring it non-const is perfectly legal. So "read-only" whould the correct term. However, who says string literal says read-only, so there's no point mentioning it anyway. – netcoder Nov 28 '12 at 14:56
5

When assigning "LINE TO BE SEPARATED" to char *line, you make line point to an constant string written in the program executable. You are not allowed to modify it. You should declare those kind of variable as const char *.

When declared as char[], your string is declared on the stack of your function. Thus, you are able to modify it.

tomahh
  • 13,441
  • 3
  • 49
  • 70
3
char *s = "any string"

is a definition of pointer which point to string or array of char(s). in the above example s is pointing to a constant string

char s[] = "any string"

is a definition of array of char(s). in the above example s is an array of char(s) which contains the charcters {'a','n','y',' ','s','t','r,'i','n','g','\0'}

strtock changes the content of your input string. it replaces the delimators in your string by the '\0' (null).

So, you can not use strtok with constant strings like this:

char *s="any string"

you can use strtok with dynamic memory or static memory like:

char *s = malloc(20 * sizeof(char)); //dynamic allocation for string
strcpy(s,"any string");


char s[20] = "any string"; //static allocation for string
char s[] = "any string"; //static allocation for string
MOHAMED
  • 41,599
  • 58
  • 163
  • 268
1

To answer your question: char* and char[] are not same type?

This:

char *line = "LINE TO BE SEPARATED";

Is a string literal defined in read only memory. You can't change this string.

This, however:

char line[] = "LINE TO BE SEPARATED";

Is now a character array (the quoted text was copied into the array) placed on the stack. You are allowed to modify the characters in this array.

So they are both character arrays, but placed in different parts of memory.

Mike
  • 47,263
  • 29
  • 113
  • 177