tags:

views:

199

answers:

7

Possible Duplicate:
What is the difference between char s[] and char *s in C?

Why is:

char *ptr = "Hello!"

different than:

char ptr[] = "Hello!"

Specifically, I don't see why you can use (*ptr)++ to change the value of 'H' in the array, but not the pointer.

Thanks!

+6  A: 

Read the C language FAQ. Specially the array and pointers sections.

Pablo Santa Cruz
Just post it next time rather than piont me to a webpage
John McGee
@John Just read it next time rather than asking a question that has been asked many times before. Have a downvote, and expect many more if that is going to be your attitude here.
anon
I also just read the FAQ, and I still don't see the answer to the question.
John McGee
@John McGee: Perhaps http://c-faq.com/aryptr/aryptr2.html (which answers your *exact* question) and http://c-faq.com/aryptr/aryptrequiv.html will help you? Or maybe the answer you're looking for is: because that's how the language is defined; arrays aren't pointers.
jamesdlin
@John McGee - you aren't making it any easier for people to help you with that kind of attitude.
Alok
Actually, it didn't answer my exact question james. I am well aware of the differences between arrays and pointers. What I wasn't aware of is that string literals aren't allowed to be modified. That is what I was looking for.
John McGee
@John McGee: Your question on string literals is also answered on the FAQ. I would recommend you to read the entire FAQ con C-lang. It's worth reading! From top to bottom. Seriously. It's very good.Good luck fellow.
Pablo Santa Cruz
Ah yes - this precise issue is addressed in Question 1.32 instead of in the 'Arrays and Pointers' section: http://c-faq.com/decl/strlitinit.html
Michael Burr
@John McGee - @Pablo showed you a great resource that answers this question, and quite possibly more questions that you'll have in the future. Teach a man to fish, if you will. A more appropriate response might of been "I can't find it in there, is there a specific example I'm missing?"
Tim Post
A: 

I think most people misunderstood the question, and I got a lot of flak for apparently not reading the C FAQ. The correct answer was that string literals are not allowed to be modified. I was not aware of this.

John McGee
John - this kind of 'answer' should be placed in a comment to another answer (as you did in the comments to Pablo's answer) or to your question. As you can see, comments-as-answers get downvoted - sometimes harshly. You may want to delete this answer.
Michael Burr
I actually don't really care about my downvotes. I would prefer just to delete the existence of this 'account', although there appears to be no way to do so.
John McGee
I think most people are reacting to your attitude, asking a question is asking for help, as such, people generally expect to be treated with respect and courtesy, the onus is on you to ask your question as clearly as possible to get the answer you want.
Keith Nicholas
A: 

Arrays automatically allocate space and they can't be relocated or resized while pointers are explicitly assigned to point to allocated space and can be relocated.

Array names are read only!

a.feng
Thanks, but it doesn't answer my question. I am asking why (*ptr)++ for the array will change the 'H' to an 'I', but not for the other case.
John McGee
+16  A: 

You can (in general) use the expression (*ptr)++ to change the value that ptr points to when ptr is a pointer and not an array (ie., if ptr is declared as char* ptr).

However, in your first example:

char *ptr = "Hello!"

ptr is pointing to a literal string, and literal strings are not permitted to be modified (they may actually be stored in memory area which are not writable, such as ROM or memory pages marked as read-only).

In you second example,

char ptr[] = "Hello!";

The array is declared and the initialization actually copies the data in the string literal into the allocated array memory. That array memory is modifiable, so (*ptr)++ works.

Note: for your second declaration, the ptr identifier itself is an array identifier, not a pointer and is not an 'lvalue' so it can't be modified (even though it converts readily to a pointer in very many situations). For example, the expression ++ptr would be invalid. I think this is the point that some other answers are trying to make.

Michael Burr
And finally, someone answered my question. If I had a registered account, I would give you an upvote. Thank you kind sir.
John McGee
@John McGee: That you posted a question means you have an "account", you have enough reputation to upvote, and you always can mark an answer as "accepted".
jamesdlin
Im too lazy to try out right now, but would (*ptr)++ in the first case really result in an compiler error? The compiler would need to analyse if ptr hasn't changed since initialization, wouldn't he?
MartinStettner
@Martin: it won't generally result in a compile-time error (maybe a warning if your compiler is smart and can detect that `ptr` points to a literal), but it will often result in a runtime error. However, it might appear to work on some platforms - but it's undefined behavior and should be regarded as a bug on any platform.
Michael Burr
@Michael: Thanks. Not to mention the cases when constant strings are shared (i.e. reused), which is much more common I think ...
MartinStettner
@jamesdlin: It won't let me upvote until I register. I just tried.
John McGee
A: 

If You use a string literal "Hello!", the literal itself becomes an array of 7 characters and gets stored somewhere in a data memory. That memory may be read only.

The statement

char *ptr = "Hello!";

defines a pointer to char and initializes it, by storing the address of the beginning of the literal (that array of 7 characters mentioned earlier) in it. Changing contents of the memory pointed to by ptr is illegal.

The statement

char ptr[] = "Hello!";

defines a char array (char ptr[7]) and initializes it, by copying characters from the literal to the array. The array can be modified.

Maciej Hehl
A: 

in C strings are arrays of characters. A pointer is a variable that contains the memory location of another variable. An array is a set of ordered data items. when you put (*ptr)++ you are getting Segmentation Fault with the pointer.

Maybe you are adding 1 to the whole string (with the pointer), instead of adding 1 to the first character of the variable (with the array).

pabiagioli
A: 

When pointing to a string literal, you should not declare the chars to be modifiable, and some compilers will warn you for this:

char *ptr = "Hello!"    /* WRONG, missing const! */

The reason is as noted by others that string literals may be stored in an immutable part of the program's memory.

The correct "annotation" for you is to make sure you have a pointer to constant char:

const char *ptr = "Hello!"

And now you see directly that you can't modify the text stored at the pointer.

kaizer.se