1

Possible Duplicate:
Difference between char *str=“STRING” and char str[] = “STRING”?

I wrote the following code:

int main()
{
    char *str = "hello";
    str[0] = 'H';
    printf("%s\n", str);
}

This gives me a segmentation fault, I cant understand why.

str is pointer to char not const char. Even if that's the case shouldn't it give a compile error like the following program:

int main()
{
    const char *str = "hello";
    str[0] = 'H';
    printf("%s\n", str);    
}

It gives an error: assignment of read-only location *str.

EDIT

If my code places the pointer to a read only location, shouldn't I get a compilation error?

Community
  • 1
  • 1
Anubhav Agarwal
  • 1,982
  • 5
  • 28
  • 40
  • Please use the search feature. If you searched you would find hundreds of the exact same question. – Marlon Oct 06 '12 at 17:14
  • @Marlon please paste a link of a duplicate question on stackoverflow – Anubhav Agarwal Oct 06 '12 at 17:16
  • The pointer is not read only. It just points to where your string is stored in memory. There is a subtle difference between the ways you can declare your string that changes how it's stored. – Andy Harris Oct 06 '12 at 17:16
  • 1
    http://stackoverflow.com/questions/11098074/pointers-and-strings-causing-segmentation-fault, http://stackoverflow.com/questions/9460260/what-is-the-difference-between-char-a-string-and-char-p-string, http://stackoverflow.com/questions/6958222/unknown-segmentation-fault, ................... "char segmentation fault" "string segmentation fault", etc. – Marlon Oct 06 '12 at 17:20
  • "If my code places the pointer to a read only location, shouldn't I get a compilation error." Why? There is nothing syntactically incorrect with the code. – Marlon Oct 06 '12 at 17:23
  • 1
    "If my code places the pointer to a read only location, shouldn't I get a compilation error." what you do is a perfectly valid assignment. What the compiler does not know is that in a standard system constant strings are placed in read-only memory. On embedded systems this may be different. – Sergey L. Oct 06 '12 at 17:24

6 Answers6

5

You assign a pointer to a constant string (which comes as a part of your text and is thus not writable memory).

Fix with char str[] = "hello"; this will create a r/w copy of the constant string on your stack.

What you do is a perfectly valid pointer assignment. What the compiler does not know is that in a standard system constant strings are placed in read-only memory. On embedded (or other weird) systems this may be different.

Depending on your system you could come with an mprotect and change the VM flags on your pointer destination to writable. So the compiler allows for this code, your OS does not though.

Sergey L.
  • 21,822
  • 5
  • 49
  • 75
  • 1
    The string literal is not `const` nor constant. It is standard array of `char` just big enough to hold all the characters plus the terminator which is not writeable under penalty of Undefined Behavior. – pmg Oct 06 '12 at 17:30
2

When you initialize a char * using a literal string, then you shouldn't try to modify it's contents: the variable is pointing to memory that doesn't belong to you.

You can use:

char str[] = "hello";
str[0] = 'H';

With this code you've declared an array which is initialized with a copy of the literal string's contents, and now you can modify the array.

pb2q
  • 58,613
  • 19
  • 146
  • 147
0

Your code has undefined behavior in runtime. You are attempting to write to a literal string, which is not allowed. Such writes may trigger an error or have undefined behavior. Your specific C compiler has str point to read-only memory, and attempting to write to that memory leads to a segmentation fault. Even though it's not const, the write is still not allowed.

epsalon
  • 2,294
  • 12
  • 19
0
char *str = "hello";

When you declare str as above, it is not guaranteed which part of memory it will be stored. str might be read-only depending on implementation. So trying to change it will cause segmentation fault.

In order to avoid segmentation faullt, declare str as an array of characters instead.

Raj
  • 4,342
  • 9
  • 40
  • 45
0
char *str = "hello";

here the string hello is a literal. string literals are always stored in read only memory. this is the reason you are getting a segmentation fault when you are trying to change the value at read only memory.

Vijay
  • 65,327
  • 90
  • 227
  • 319
0

Declaring str as char* reserves memory for the pointer, but not for the string. The compiler can put the memory for "hello" anywhere he likes. You have no guarantee that str[i] is writable, so that's why in some compilers this results in a seg fault.

If you want to make sure that the string is in writable memory, then you have to allocate memory using alloc() or you can use

char str[] = "hello";
Zane
  • 926
  • 8
  • 21