1

Array is treated as constant pointer,so we cannot change the pointer value,I am unable to figure out like lets suppose-

  a[5]="hello";
  a="hai"; // I Know This not possible but why if below a[0]='a' is possible?
  a[0]='a' ;//this is possible because a is store in stack memory.

Now coming to pointer

 char *a="hello";
  a="hai"; //i know this is possible because string are store in code section which is read only memory then why it is changed?  
  a[0]='a' //Not possible  because it is store in stack and string is store in code section if above a="hai" is possible then why a[0]='a' is not possible?

I am new here and i have been blocked 2 times so please apart from demoralizing by making vote down please help me to understand the concept

  • 2
    read this: http://stackoverflow.com/a/12795948/3516541 also, you're going to need one more space for the null terminator of "hello" – Ben Jun 10 '14 at 16:53
  • 1
    Voting down or closing a question is not to demoralize you or something like that. In particular the second, just points you to a question that already has an answer on this site, often already a lot of answers. Please search the SO site (and other online resources) before you ask here, it is as simple as that. There is e.g a C FAQ out there that tells you about the difference between pointers and arrays. – Jens Gustedt Jun 10 '14 at 18:49

2 Answers2

6

Array is treated as constant pointer

No, it isn't treated as such. An array is treated as... an array.

a="hai"; // I Know This not possible but why

Because the language definition says so (more precisely, because an array is not a modifiable lvalue). And it says so because it doesn't make sense.

Your comments about "the stack" and "the code" are not relevant; the modifiability of the objects in an array does not depend on where they are stored. That's an implementation detail.

6

Assume the following declarations:

char arr[6] = "hello";
char *ap    = "hello";

Here's one possible memory map showing the outcome of those declarations (all addresses are made up out of thin air and don't represent any real-world architecture):

Item            Address        0x00 0x01 0x02 0x03
----            -------        ---- ---- ---- ----
"hello"         0x00008000      'h'  'e'  'l'  'l'
"hai"           0x00008004      'o' 0x00  'h'  'a'
                0x00008008      'i' 0x00 0x?? 0x??
                ...
arr             0x82340000      'h'  'e'  'l'  'l'
                0x82340004      'o'  0x00 0x?? 0x??
ap              0x82340008      0x00 0x00 0x80 0x00

The string literal "hello" is stored as a 6-element array of char with static storage duration at address 0x0008000. The string literal "hai" is stored as a 4-element array of char with static storage duration at address 0x00080006. The contents of a string literal may be stored in a read-only section of memory (depends on the platform). The behavior on attempting to modify the contents of a string literal is undefined; the code is considered erroneous, but the compiler isn't required to handle the situation in any particular way. You may get a segfault, or the change simply won't be applied, or the change will be applied as you expect. I'm assuming that multiple instances of a string literal in the source code will map to a single instance in memory (which is the usual case IME).

Except when it is the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element of the array. The resulting pointer is a non-modifiable lvalue.

The declaration

char arr[6] = "hello";

declares arr as a 6-element array of char with auto extent, and the contents of the string literal "hello" are copied into it. You can modify the values of arr[0] through arr[5] all you want, so you can write

a[0] = 'a';

but you cannot write something like

arr = "hai";

because while both of the expressions arr and "hai" are converted to pointer values as described above, arr isn't a pointer variable; there's no storage associated with arr apart from the array elements themselves, so there's no place to assign the result of "hai" (0x00008006).

The declaration

char *ap    = "hello";

declares ap as a pointer to char, and assigns the result of the expression "hello" to it. In this case, the string literal is not the operand of the sizeof or unary & operators, and it isn't being used to initialize the contents of an array, so it is converted to a pointer expression, and its value is the address of the first element of the array, or 0x0008000.

This is almost the mirror opposite of arr; you cannot update the contents of ap[0] through ap[5], but you can assign a new pointer value to ap, so

ap = "hai";

works. After doing so, your memory map would look like

Item            Address        0x00 0x01 0x02 0x03
----            -------        ---- ---- ---- ----
"hello"         0x00008000      'h'  'e'  'l'  'l'
"hai"           0x00008004      'o' 0x00  'h'  'a'
                0x00008008      'i' 0x00 0x?? 0x??
                ...
arr             0x82340000      'a'  'e'  'l'  'l'
                0x82340004      'o'  0x00 0x?? 0x??
ap              0x82340008      0x00 0x00 0x80 0x06
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • Though the answer sounds super fantastic and logical, I never came across similar explanation anywhere online and not much upvotes one this answer. Will love to know the references or at least some other links to explain pointers and arrays in this manner. – MsA Dec 05 '18 at 04:11
  • Onlike people go on saying "array is treated as constant pointer. So we cannot change the pointer value.", which doesn't sound great and feels misleading when we read above answer. – MsA Dec 05 '18 at 05:20
  • 2
    @Anir - this comes from the [C language standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) (online draft, which is not the *official* version, but close enough), particularly section 6.3.2.1. – John Bode Dec 05 '18 at 14:54