tags:

views:

235

answers:

4

Consider the following code.

int main(void) {
    char * test = "abcdefghijklmnopqrstuvwxyz";
    test[5] = 'x';
    printf("%s\n", test);
    return EXIT_SUCCESS;
}

In my opinion, this should print abcdexghij. However, it just terminates without printing anything.

int main(void) {
    char * test = "abcdefghijklmnopqrstuvwxyz";
    printf("%s\n", test);
    return EXIT_SUCCESS;
}

This however, works just fine, so did I misunderstand the concept of manipulating C strings or something? In case it is important, I'm running Mac OS X 10.6 and it is a 32-bit binary I'm compiling.

+22  A: 

Char pointers defined with an initialization value go into a read-only segment. To make them modifiable, you either need to create them on the heap (e.g. with new/malloc) or define them as an array.

Not modifiable:

char * foo = "abc";

Modifiable:

char foo[] = "abc";
Joe
Whoops--thanks for the edit.
Joe
foo[0] = 'x' still segfaults on my box
pm100
+2  A: 

You should get into the habit of matching the type of the variable with the type of the initialiser. In this case:

const char* test = "abcdefghijklmnopqrstuvwxyz";

That way you will get a compiler error rather than a run-time error. Cranking your compiler warning level up to max may also help avoid such pitfalls. Why this is not an error in C is probably historical; early compilers allowed it and disallowing it might have broken too much existing code when the language was standardised. Now however operating systems do not allow it so it is academic.

Clifford

Clifford
+1  A: 

String literals may not be modifiable; it's best to assume they aren't. See here for more details.

John Bode
A: 

Do:

 char * bar = strdup(foo);
 bar[5] = 'x';

strdup makes a modifiable copy.

And yes, you should really test that strdup didn't return NULL.

pm100
...and free(bar) at the end if you use strdup()!
Drew Hall