2

When we do

char *p ="house";
 p = 'm';

Its not allowed.

But when we do

 char p[] = "house";
 p[0] = 'm';
 printf(p);

It gives O/P as : mouse

I am not able to understand how and where C does memory allocation for string literals?

3
  • Earlier this could be done with compiler option -fwriteable-strings. Now *p = "house"; is a const. Commented Oct 15, 2011 at 0:06
  • @Matty: No, it wouldn't work. It would compile, but it would cause undefined behavior and most probably crash. Commented Oct 15, 2011 at 0:07
  • 1
    @ott--: Yes, you can use a compiler option to enable writable string literals (if your compiler happens to have such an option), but unless you need to maintain very old code, you shouldn't. String literals should be treated as read-only. Commented Oct 15, 2011 at 0:11

3 Answers 3

6

char p[] = "house";

"house" is a string literal stored in a read only location, but, p is an array of chars placed on stack in which "house" is copied.

However, in char *p = "house";, p actually points to the read-only location which contains the string literal "house", thus modifying it is UB.

A note from the standard 6.7.8 Initialization

14 An array of character type may be initialized by a character string literal, optionally enclosed in braces. Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

So you basically have an array of characters. It should not be so difficult or puzzle you in understanding how this array gets modified if you have used arrays of ints, floats etc.

Sign up to request clarification or add additional context in comments.

Comments

0

When you use char *p="house" - the compiler collects all the "house" strings and puts them in one read only space.

When you use char p[]="house" the compiler creates space for the string as an array in the local scope.

Basic difference is that 1000's of pointer could share the first one (which is why you cannot modify) and the second is local to the scope - so as long as it stays the same size it is modifiable.

1 Comment

But when I use int array_int = {1,2,3}; and int *array_int_ptr = array_int; and array_int_ptr[0] = 4...I am able to change its value...also if I write int * int_ptr = {1,2,3}, I am not able to access int_ptr[1] or int_ptr[2]..it gives Segmentation fault...how does this work then
0
char *p = "house";  // const char* p = "house";

String literal "house" resides in read only location and cannot be modified. Now what you are doing is -

*p = 'm' ; // trying to modify read-only location; Missed the dereferencing part

Now,

char p[] = "house"; 

"house" is copied to the array p. So, it's contents are modifiable. So, this actually works.

p[0] = 'm'; // assigning `m` at 0th index.

3 Comments

p is a pointer. Only when you declare it an array does it become non-modifiable.
But when I use int array_int = {1,2,3}; and int *array_int_ptr = array_int; and array_int_ptr[0] = 4...I am able to change its value...also if I write int * int_ptr = {1,2,3}, I am not able to access int_ptr[1] or int_ptr[2]..it gives Segmentation fault...how does this work ?
Please have a look at the example. If you have a copy of the content, you can modify it. And using [] during initialization, gets you a copy of the intializer list to the variable. ideone.com/mz5mC

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.