Here's a hypothetical memory map, showing the results of the two declarations:
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
0x00008000: 'n' 'o' 'w' ' ' 'i' 's' ' ' 't'
0x00008008: 'h' 'e' ' ' 't' 'i' 'm' 'e' '\0'
...
amessage:
0x00500000: 'n' 'o' 'w' ' ' 'i' 's' ' ' 't'
0x00500008: 'h' 'e' ' ' 't' 'i' 'm' 'e' '\0'
pmessage:
0x00500010: 0x00 0x00 0x80 0x00
The string literal "now is the time" is stored as a 16-element array of char at memory address 0x00008000. This memory may not be writable; it's best to assume that it's not. You should never attempt to modify the contents of a string literal.
The declaration
char amessage[] = "now is the time";
allocates a 16-element array of char at memory address 0x00500000 and copies the contents of the string literal to it. This memory is writable; you can change the contents of amessage to your heart's content:
strcpy(amessage, "the time is now");
The declaration
char *pmessage = "now is the time";
allocates a single pointer to char at memory address 0x00500010 and copies the address of the string literal to it.
Since pmessage points to the string literal, it should not be used as an argument to functions that need to modify the string contents:
strcpy(amessage, pmessage); /* OKAY */
strcpy(pmessage, amessage); /* NOT OKAY */
strtok(amessage, " "); /* OKAY */
strtok(pmessage, " "); /* NOT OKAY */
scanf("%15s", amessage); /* OKAY */
scanf("%15s", pmessage); /* NOT OKAY */
and so on. If you changed pmessage to point to amessage:
pmessage = amessage;
then it can be used everywhere amessage can be used.
Answer from John Bode on Stack OverflowHere's a hypothetical memory map, showing the results of the two declarations:
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
0x00008000: 'n' 'o' 'w' ' ' 'i' 's' ' ' 't'
0x00008008: 'h' 'e' ' ' 't' 'i' 'm' 'e' '\0'
...
amessage:
0x00500000: 'n' 'o' 'w' ' ' 'i' 's' ' ' 't'
0x00500008: 'h' 'e' ' ' 't' 'i' 'm' 'e' '\0'
pmessage:
0x00500010: 0x00 0x00 0x80 0x00
The string literal "now is the time" is stored as a 16-element array of char at memory address 0x00008000. This memory may not be writable; it's best to assume that it's not. You should never attempt to modify the contents of a string literal.
The declaration
char amessage[] = "now is the time";
allocates a 16-element array of char at memory address 0x00500000 and copies the contents of the string literal to it. This memory is writable; you can change the contents of amessage to your heart's content:
strcpy(amessage, "the time is now");
The declaration
char *pmessage = "now is the time";
allocates a single pointer to char at memory address 0x00500010 and copies the address of the string literal to it.
Since pmessage points to the string literal, it should not be used as an argument to functions that need to modify the string contents:
strcpy(amessage, pmessage); /* OKAY */
strcpy(pmessage, amessage); /* NOT OKAY */
strtok(amessage, " "); /* OKAY */
strtok(pmessage, " "); /* NOT OKAY */
scanf("%15s", amessage); /* OKAY */
scanf("%15s", pmessage); /* NOT OKAY */
and so on. If you changed pmessage to point to amessage:
pmessage = amessage;
then it can be used everywhere amessage can be used.
True, but it's a subtle difference. Essentially, the former:
char amessage[] = "now is the time";
Defines an array whose members live in the current scope's stack space, whereas:
char *pmessage = "now is the time";
Defines a pointer that lives in the current scope's stack space, but that references memory elsewhere (in this one, "now is the time" is stored elsewhere in memory, commonly a string table).
Also, note that because the data belonging to the second definition (the explicit pointer) is not stored in the current scope's stack space, it is unspecified exactly where it will be stored and should not be modified.
As pointed out by Mark, GMan, and Pavel, there is also a difference when the address-of operator is used on either of these variables. For instance, &pmessage returns a pointer of type char**, or a pointer to a pointer to chars, whereas &amessage returns a pointer of type char(*)[16], or a pointer to an array of 16 chars (which, like a char**, needs to be dereferenced twice as litb points out).
What is the difference between an array and a pointer in C, and when should I use one over the other? - Stack Overflow
In c, what is the difference between char *, char **, and char ***?
-
A
char *is a pointer to achar. The value stored in achar *is a memory address, and the value stored at that memory address is achar. -
A
char **is a pointer to a pointer to achar; it's a pointer to achar *. The value stored in achar **is a memory address, and the value stored at that memory address is achar *. -
A
char ***is a pointer to a pointer to a pointer to achar; it's a pointer to achar **. The value stored in achar ***is a memory address, and the value stored at that memory address is achar **.
Difference between pointer to pointer and 2d array
Difference between char * and char[]?
Is an array a pointer in C?
Which is faster: pointer or array in C?
Can we assign an array to a pointer in C?
Videos
Any video I watch, or any article I read, I always see arrays being referred to as "pointers", or the phrase, "an array is a pointer in itself". I know that we can represent arrays in a pointer-like fashion and that &array-name[0] is the address of the 0th element or in essence, the starting address of the array. But can we call an array a pointer? If my memory serves right, whenever we create pointers, the are allocated memory from the heap memory instead of the stack memory and it is exactly opposite for static arrays.
If so, then why do people refer to arrays as pointers many times? I read this answer on StackOverflow and it seemed pretty valid to me yet I do not get it why are the above phrases/jargon used by people?
Could I please get some explanation on this and some clarification on this topic? It would be of much help. This whole thing is bugging me for the last 4-5 days.
Thank you :)