Reputation: 15217
Kernighan & Ritchie 2nd ed. says:
The correspondence between indexing and pointer arithmetic is very close. By definition, the value of a variable or expression of type array is the address of element zero of the array. Thus after the assignment
pa = &a[0];
pa
anda
have identical values. Since the name of an array is a synonym for the location of the initial element, the assignmentpa=&a[0]
can also be written as
pa = a;
Rather more surprising, at least at first sight, is the fact that a reference to
a[i]
can also be written as*(a+i).
In evaluatinga[i]
, C converts it toa[i]
immediately; the two forms are equivalent. Applying the operator & to both parts of this equivalence, it follows thatand
are also identical:a+i
is the address of thei
-th element beyond a. As the other side of this coin, ifpa
is a pointer, expressions may use it with a subscript;pa[i]
is identical to*(pa+i)
. In short, an array-and-index expression is equivalent to one written as a pointer and offset.
And after reading this, I expect this two programs work identically:
/* Program 1 */
#include <stdio.h>
int main()
{
char arr[] = "hello";
arr[0] = 'H';
printf("%s\n", arr);
}
/* Program 2 */
#include <stdio.h>
int main()
{
char *arr = "hello";
arr[0] = 'H';
printf("%s\n", arr);
}
But only the first one is actually works. With the second one I get segmentation fault.
Why? Reference to an authoritative source would be much appreciated.
Upvotes: 1
Views: 83
Reputation: 15217
K&R (5.5 Character Pointers and Functions):
There is an important difference between these definitions:
char amessage[] = "now is the time"; /* an array */ char *pmessage = "now is the time"; /* a pointer */
amessage
is an array, just big enough to hold the sequence of characters and′\0′
that initializes it. Individual characters within the array may be changed butamessage
will always refer to the same storage. On the other hand,pmessage
is a pointer, initialized to point to a string constant; the pointer may subsequently be modified to point elsewhere, but the result is undefined if you try to modify the string contents.
Upvotes: 0
Reputation: 409422
When you define and initialize the array, all of the array is allocated in modifiable memory (usually the stack), and so you can modify the array any way you want.
When you use a string literal, the compiler will give you a pointer to a read-only zero-terminated array of char
. Attempting to modify this array (which you do in the second example) leads to undefined behavior.
Upvotes: 3
Reputation: 106102
That's because the arr
in first snippet is a char
array and can be modified while in second snippet it is a string literal which is not subjected to change.
String literals might be stored in read only section of memory and modifying it will invoke undefined behavior.
Upvotes: 1
Reputation: 122493
It has nothing to do with pointer arithmetic. It's because in the second program:
char *arr = "hello";
arr
points to a string literal, which can NOT be modified.
Upvotes: 2