C: differences between char pointer and array [duplicate]
Asked Answered
I

14

160

Consider:

char amessage[] = "now is the time";
char *pmessage = "now is the time";

I read from The C Programming Language, 2nd Edition that the above two statements don't do the same thing.

I always thought that an array is an convenient way to manipulate pointers to store some data, but this is clearly not the case... What are the "non-trivial" differences between arrays and pointers in C?

Indult answered 26/8, 2009 at 16:0 Comment(6)
I may be misremembering this, but I'd like to point out that that you can use the [] notation on pointers and the * notation on arrays. The only big difference from the code's point of view is that amessage's value cannot change, so amessage++ should fail (but I believe *(amessage+1) will succeed. There are other differences internally I believe, but they almost never actually matter.Emmy
Oh, and generally (not in the cases you mentioned), arrays automatically allocate memory, pointers you have to allocate your own memory. Yours should both just point to blocks of memory that were allocated as part of the program loading.Emmy
Along with the K&R (which is a great book, by the way) I'd suggest you read pw2.netcom.com/~tjensen/ptr/cpoint.htm - in interim.Ashlaring
See https://mcmap.net/q/107919/-what-is-the-difference-between-char-array-and-char-pointer-in-cTieck
Closing this as duplicate since we had two "canonical" FAQ threads about this very same question.Titoism
Possibly related: https://mcmap.net/q/111794/-extern-declaration-t-v-s-tEmancipator
A
119

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).

Anthropometry answered 26/8, 2009 at 16:0 Comment(18)
While true, this is hardly the biggest difference. What's the difference between &amessage and &pmessage, for example?Opine
&pmessage will be the address of pmessage, somewhere on the stack. Likewise, &amessage will be the address of the array on the stack, same as amessage. However, &amessage has a different type than amessage.Mcgannon
No, it's not undefined. The difference is that the type of &pmessage is char** - pointer to pointer to char, and the type of &amessage is char(*)[16] - pointer to array of 16 chars. Those two types are not compatible (the second one, in particular, is simply address of the first character in the string, while the first one is address of variable that stores the address of the first character).Steam
Weird, I guess C does do that. I figured &amessage would be invalid as amessage is resolved to a code-constant pointer . . .Anthropometry
By which I mean, you can do something like char* test = amessage; and it works fine, but apparently &amessage is still only one pointer away from the data.Anthropometry
Wouldn't both of these (because they are being assigned to a string literal) just point to that literal where it was loaded by the program? I don't think either makes a copy on the stack, but I could easily be wrong--it seems like at least the array SHOULD make a copy...Emmy
@Bill: Nah, cause the array version is actually just a shortcut for array instantiation. So the array is allocated in the stack, and then loaded with the string's data.Anthropometry
char* test = amessage; works because the array is implicitly converted. Just like char* test = 0; works. This doesn't mean that amessage is an address in all cases. Only in those where a conversion to a pointer is done. In &amessage, it's not done. Same as in &"123": No conversion to pointer done.Moonshine
To get from &amessage to the first character, two dereference operations are needed: **&amessage = 'c';. One will evaluate to the array, and the another one will evaluate to the character.Moonshine
@litb: Isn't &amessage still a conversion to pointer, since it returns a pointer to the array (which is the same as the implicitly converted pointer, just with a slightly different typedef)?Anthropometry
er, check the edit now, is that more correct?Anthropometry
This looks like a community wiki entry now...Ser
@Walt W, yeah the addresses in both cases are the same, just the type differ. However, technically there is no conversion applied to amessage prior to applying the address-of operator (likewise, with the sizeof operator)Moonshine
"stack space" has nothing to do with this question. Some systems don't even have stacks; and even on the ones that do, stack space would not be used if these declarations were at file scope.Koby
If i have char *b = "Hello" , and if i have char c[] = "hello" , both works , if for first case i do b = "helloworld" , it works too , but for second case if i do c = "helloworld" , it does not why so ?Yarmouth
@SurajJain with char *b, you have a pointer variable that was pointing to "Hello" and you are changing it to point at "helloworld" instead. With char c[], you have an array, which is kind of a fixed pointer to a known chunk of memory. Since writing c = "helloworld" is trying to reassign a fixed pointer, it won't work.Anthropometry
I learned that array name cannot be used as l value that it why it doesn't work.??Yarmouth
No, I don't believe that is why. See previous answer.Anthropometry
P
173

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.

Pless answered 27/8, 2009 at 14:57 Comment(24)
@m47h: If you're going to insist on English even in a little throwaway comment, then at least remove the italics as well. "and so on" just looks wrong.Pless
@JohnBode: Just saw it right there and it confused me so i changed it, so never mindSulfurous
The last line is not quite true: the behaviour is different if used as sizeof message or &pmessage .Koby
@JohnBode, Since amessage copied from memory address 0x00008000, when will this memory address being recollect by system, right after it get copied by amessage? And what will happened when pmessage points to another string, will the content of 0x00008000 be removed right after pmessage pointer changes its point address?Ancestor
@zen: Setting pmessage to point to another string will have absolutely no effect on the contents of the string literal stored at 0x0000800. The storage for that string literal won't be released until the program exits.Pless
@JohnBode, my friends told me that amessage and pmessage are both pointers, amessage points to the address of the first char of the array, is him right? If this is true, when using sizeof(amessage) and sizeof(pmessage) I got different result, the former gives the actual length, meanwhile the later gives me the length of its address, is this an inner mechanism of sizeof?Ancestor
@Zen: your friends are incorrect; arrays like amessage are not pointers. Array objects do not store an address anywhere (which should be clear from the memory map in my answer). Rather, array expressions will "decay" to pointer types unless they are operands of the unary & or sizeof operators (hence the difference in behavior for sizeof).Pless
@Zen: see this answer for more details.Pless
@JohnBode i am confused, is there any validity to the 2nd paragraph here then? c.learncodethehardway.org/book/ex15.html#explaining-pointersPuritanism
@ChrisM: It's not wrong, but it is a bit imprecise (which is not surprising, given the learning level for which it is written). The object to which ages refers only sets aside storage for the array elements themselves; it does not store a pointer value. When the code is compiled, any occurrence of the expression ages is replaced with a pointer to the first element of the array object (unless ages is the operand of sizeof or unary &).Pless
@Ancestor Maybe you should review your question at the point of view of the compiler, because for the compiler, all those symbols will become addresses. A littile bit assembly language learning is enough to understand this.Sima
Just curious,, you say with char amessage[] = "now is the time"; the contents of the string literal are copied into the array.. where's the original string literal? Is it stored in some static read-only place of the program with nothing pointing to it? Does the compiler just handle this behind the scenes somehow? I could probably look at some assembly to get an idea.Madalynmadam
@yano: string literals are stored as arrays of char such that they are available over the lifetime of the program; they may be stored in a read-only memory segment, although I've worked on platforms where they were modifiable.Pless
If i have char *b = "Hello" , and if i have char c[] = "hello" , both works , if for first case i do b = "helloworld" , it works too , but for second case if i do c = "helloworld" , it does not why so ?Yarmouth
@SurajJain: b is a pointer, and you're setting it to point to a different address. c is an array, and array expressions cannot be the target of an assignment (for reasons that won't fit into a comment). You cannot change the array contents using the = operator. To change the contents of an array, you must use a library function like strcpy or memcpy or assign each element individually. Also, the array must be large enough to accomodate the new string - it won't automatically be resized if it's too small for the new string.Pless
why array expression cannot be target of assignment ? You can provide link to the answer. ThanksYarmouth
@SurajJain: Mainly because the language definition says so. See the online draft of the C language standard, section 6.3.2.1, particularly subclauses 1 and 3. The motivation for the rule is best explained by Ritchie himself (particularly the section titled "Embryonic C".Pless
Thank You Sir , i will do so , one favor i want from you if you can , can you please see this question #34826536 , and confirm if the answer is correct. It is bugging me for a year now.Yarmouth
@SurajJain: Strictly speaking, the answer would be "the conversion specifier %d expects an int type argument, but you're passing a char value, so the behavior is undefined and pretty much any result is possible". You could then explore the particulars of the platform to see how you could get that specific value, but from the perspective of the C language, the code is simply wrong.Pless
Doesn't Char get promoted to integer , becasue printf is a varadic function. And in promotion value stays same.Yarmouth
#1256275Yarmouth
@SurajJain: 7.26.6.1, subclause 9:"...If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined." Yes, char objects get promoted to int when passed to variadic functions - in the case of printf, using the hh length modifier will convert the argument back to char before printing.Pless
If they do get converted what is the problem using %d .Yarmouth
This Question has exact same thing as mine , please see this https://mcmap.net/q/16770/-type-casting-char-pointer-to-integer-pointer If they do get converted what is the problem using %d .Yarmouth
A
119

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).

Anthropometry answered 26/8, 2009 at 16:0 Comment(18)
While true, this is hardly the biggest difference. What's the difference between &amessage and &pmessage, for example?Opine
&pmessage will be the address of pmessage, somewhere on the stack. Likewise, &amessage will be the address of the array on the stack, same as amessage. However, &amessage has a different type than amessage.Mcgannon
No, it's not undefined. The difference is that the type of &pmessage is char** - pointer to pointer to char, and the type of &amessage is char(*)[16] - pointer to array of 16 chars. Those two types are not compatible (the second one, in particular, is simply address of the first character in the string, while the first one is address of variable that stores the address of the first character).Steam
Weird, I guess C does do that. I figured &amessage would be invalid as amessage is resolved to a code-constant pointer . . .Anthropometry
By which I mean, you can do something like char* test = amessage; and it works fine, but apparently &amessage is still only one pointer away from the data.Anthropometry
Wouldn't both of these (because they are being assigned to a string literal) just point to that literal where it was loaded by the program? I don't think either makes a copy on the stack, but I could easily be wrong--it seems like at least the array SHOULD make a copy...Emmy
@Bill: Nah, cause the array version is actually just a shortcut for array instantiation. So the array is allocated in the stack, and then loaded with the string's data.Anthropometry
char* test = amessage; works because the array is implicitly converted. Just like char* test = 0; works. This doesn't mean that amessage is an address in all cases. Only in those where a conversion to a pointer is done. In &amessage, it's not done. Same as in &"123": No conversion to pointer done.Moonshine
To get from &amessage to the first character, two dereference operations are needed: **&amessage = 'c';. One will evaluate to the array, and the another one will evaluate to the character.Moonshine
@litb: Isn't &amessage still a conversion to pointer, since it returns a pointer to the array (which is the same as the implicitly converted pointer, just with a slightly different typedef)?Anthropometry
er, check the edit now, is that more correct?Anthropometry
This looks like a community wiki entry now...Ser
@Walt W, yeah the addresses in both cases are the same, just the type differ. However, technically there is no conversion applied to amessage prior to applying the address-of operator (likewise, with the sizeof operator)Moonshine
"stack space" has nothing to do with this question. Some systems don't even have stacks; and even on the ones that do, stack space would not be used if these declarations were at file scope.Koby
If i have char *b = "Hello" , and if i have char c[] = "hello" , both works , if for first case i do b = "helloworld" , it works too , but for second case if i do c = "helloworld" , it does not why so ?Yarmouth
@SurajJain with char *b, you have a pointer variable that was pointing to "Hello" and you are changing it to point at "helloworld" instead. With char c[], you have an array, which is kind of a fixed pointer to a known chunk of memory. Since writing c = "helloworld" is trying to reassign a fixed pointer, it won't work.Anthropometry
I learned that array name cannot be used as l value that it why it doesn't work.??Yarmouth
No, I don't believe that is why. See previous answer.Anthropometry
M
13

An array contains the elements. A pointer points to them.

The first is a short form of saying

char amessage[16];
amessage[0] = 'n';
amessage[1] = 'o';
...
amessage[15] = '\0';

That is, it is an array that contains all the characters. The special initialization initializes it for you, and determines it size automatically. The array elements are modifiable - you may overwrite characters in it.

The second form is a pointer, that just points to the characters. It stores the characters not directly. Since the array is a string literal, you cannot take the pointer and write to where it points

char *pmessage = "now is the time";
*pmessage = 'p'; /* undefined behavior! */

This code would probably crash on your box. But it may do anything it likes, because its behavior is undefined.

Moonshine answered 26/8, 2009 at 16:11 Comment(1)
sir , i want to ask one thing can i use %d in printf for char , i was thinking that i can because they are default promoted to integer , but this answer says otherwise , i am confused , if you could clear the confusion , it would be a great help https://mcmap.net/q/16633/-dereferencing-this-pointer-gives-me-46-but-i-am-not-sure-whyYarmouth
L
7

If an array is defined so that its size is available at declaration time, sizeof(p)/sizeof(type-of-array) will return the number of elements in the array.

Lackadaisical answered 26/8, 2009 at 16:0 Comment(1)
All other answers focused on the "point to string literal address vs. copy string's chars into array", which is valid but is specific to the OP's example code. All failed to mention this (the different result of sizeof()), which is -in my opinion- a very important difference between arrays and pointers.Tytybald
M
7

I can't add usefully to the other answers, but I will remark that in Deep C Secrets, Peter van der Linden covers this example in detail. If you are asking these kinds of questions I think you will love this book.


P.S. You can assign a new value to pmessage. You can't assign a new value to amessage; it is immutable.

Maund answered 26/8, 2009 at 17:18 Comment(1)
@Norman, Surely there's a free version of the book?Tieck
S
4

Along with the memory for the string "now is the time" being allocated in two different places, you should also keep in mind that the array name acts as a pointer value as opposed to a pointer variable which pmessage is. The main difference being that the pointer variable can be modified to point somewhere else and the array cannot.

char arr[] = "now is the time";
char *pchar = "later is the time";

char arr2[] = "Another String";

pchar = arr2; //Ok, pchar now points at "Another String"

arr = arr2; //Compiler Error! The array name can be used as a pointer VALUE
            //not a pointer VARIABLE
Sassy answered 26/8, 2009 at 16:30 Comment(0)
C
4

The first form (amessage) defines a variable (an array) which contains a copy of the string "now is the time".

The second form (pmessage) defines a variable (a pointer) that lives in a different location than any copy of the string "now is the time".

Try this program out:

#include <inttypes.h>
#include <stdio.h>

int main (int argc, char *argv [])
{
     char  amessage [] = "now is the time";
     char *pmessage    = "now is the time";

     printf("&amessage   : %#016"PRIxPTR"\n", (uintptr_t)&amessage);
     printf("&amessage[0]: %#016"PRIxPTR"\n", (uintptr_t)&amessage[0]);
     printf("&pmessage   : %#016"PRIxPTR"\n", (uintptr_t)&pmessage);
     printf("&pmessage[0]: %#016"PRIxPTR"\n", (uintptr_t)&pmessage[0]);

     printf("&\"now is the time\": %#016"PRIxPTR"\n",
            (uintptr_t)&"now is the time");

     return 0;
}

You'll see that while &amessage is equal to &amessage[0], this is not true for &pmessage and &pmessage[0]. In fact, you'll see that the string stored in amessage lives on the stack, while the string pointed at by pmessage lives elsewhere.

The last printf shows the address of the string literal. If your compiler does "string pooling" then there will be only one copy of the string "now is the time" -- and you'll see that its address is not the same as the address of amessage. This is because amessage gets a copy of the string when it is initialized.

In the end, the point is that amessage stores the string in its own memory (on the stack, in this example), while pmessage points to the string which is stored elsewhere.

Chiropody answered 26/8, 2009 at 17:55 Comment(6)
That's wrong. The array holds a copy of the string literal - it's not the same array.Moonshine
Maybe I was a bit ambiguous. Let me clarify: there is a variable named amessage. There is a string whose contents are "now is the time". The address of amessage is the same as the address of the "n" in that string. That's the relationship I'm talking about. Granted, there may be other copies of "now is the time" floating about in the program's address space, but I'm talking about the copy that's stored in the array.Chiropody
Now it makes much sense to me. Thanks for the further explanation!Moonshine
@DanMoulding I have edited to combine the edit with the original text. As it stood, the unedited opening paragraph was misleading. Hope this is OK!Koby
@Koby how is &amessage same as &amessage[0] Yarmouth
@DanMoulding isn't amessage the pointer to first element of character array that means amessage points to amessage[0] so &amessage[0] = amessage but how is &amessage(Address of amessage) is same as amessage[0] Yarmouth
A
4

A pointer is just a variable that holds a memory address. Notice that you are playing with "string literals" which is another issue. The differences are explained inline. Basically:

#include <stdio.h>

int main ()
{
    char amessage[] = "now is the time"; /* Attention you have created a "string literal" */

    char *pmessage = "now is the time";  /* You are REUSING the string literal */


    /* About arrays and pointers */

    pmessage = NULL; /* All right */
    amessage = NULL; /* Compilation ERROR!! */

    printf("%d\n", sizeof (amessage)); /* Size of the string literal*/
    printf("%d\n", sizeof (pmessage)); /* Size of pmessage is platform dependent - size of memory bus (1,2,4,8 bytes)*/

    printf("%p, %p\n", pmessage, &pmessage);  /* These values are different !! */
    printf("%p, %p\n", amessage, &amessage);  /* These values are THE SAME!!. There is no sense in retrieving "&amessage" */


    /* About string literals */

    if (pmessage == amessage)
    {
        printf("A string literal is defined only once. You are sharing space");

        /* Demonstration */
        "now is the time"[0] = 'W';
        printf("You have modified both!! %s == %s \n", amessage, pmessage);
    }

    /* Hope it was useful*/
    return 0;
}
Apace answered 26/10, 2012 at 10:25 Comment(1)
Depending on your compiler the string literals can behave differently.Apace
Z
4

differences between char pointer and array

C99 N1256 draft

There are two different uses of character string literals:

  1. Initialize char[]:

    char c[] = "abc";      
    

    This is "more magic", and described at 6.7.8/14 "Initialization":

    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 this is just a shortcut for:

    char c[] = {'a', 'b', 'c', '\0'};
    

    Like any other regular array, c can be modified.

  2. Everywhere else: it generates an:

    So when you write:

    char *c = "abc";
    

    This is similar to:

    /* __unnamed is magic because modifying it gives UB. */
    static char __unnamed[] = "abc";
    char *c = __unnamed;
    

    Note the implicit cast from char[] to char *, which is always legal.

    Then if you modify c[0], you also modify __unnamed, which is UB.

    This is documented at 6.4.5 "String literals":

    5 In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence [...]

    6 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

6.7.8/32 "Initialization" gives a direct example:

EXAMPLE 8: The declaration

char s[] = "abc", t[3] = "abc";

defines "plain" char array objects s and t whose elements are initialized with character string literals.

This declaration is identical to

char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };

The contents of the arrays are modifiable. On the other hand, the declaration

char *p = "abc";

defines p with type "pointer to char" and initializes it to point to an object with type "array of char" with length 4 whose elements are initialized with a character string literal. If an attempt is made to use p to modify the contents of the array, the behavior is undefined.

GCC 4.8 x86-64 ELF implementation

Program:

#include <stdio.h>

int main(void) {
    char *s = "abc";
    printf("%s\n", s);
    return 0;
}

Compile and decompile:

gcc -ggdb -std=c99 -c main.c
objdump -Sr main.o

The output contains:

 char *s = "abc";
8:    48 c7 45 f8 00 00 00     movq   $0x0,-0x8(%rbp)
f:    00
         c: R_X86_64_32S    .rodata

Conclusion: GCC stores char* it in .rodata section, not in .text.

If we do the same for char[]:

 char s[] = "abc";

we obtain:

17:   c7 45 f0 61 62 63 00    movl   $0x636261,-0x10(%rbp)

so it gets stored in the stack (relative to %rbp).

Note however that the default linker script puts .rodata and .text in the same segment, which has execute but no write permission. This can be observed with:

readelf -l a.out

which contains:

Section to Segment mapping:
 Segment Sections...
  02     .text .rodata
Ziagos answered 5/6, 2015 at 7:39 Comment(0)
P
3

The second one allocates the string in some read-only section of the ELF. Try the following:

#include <stdio.h>

int main(char argc, char** argv) {
    char amessage[] = "now is the time";
    char *pmessage = "now is the time";

    amessage[3] = 'S';
    printf("%s\n",amessage);

    pmessage[3] = 'S';
    printf("%s\n",pmessage);
}

and you will get a segfault on the second assignment (pmessage[3]='S').

Preconcert answered 26/8, 2009 at 16:0 Comment(2)
That's a very implementation-centric explanation. What if it's a popular compiler that doesn't target ELF (e.g. VC++)?Steam
You might get a segfault. That's undefined.Haldas
P
1

The previous answers must have answered your question. But I would like to suggest you to read the paragraph "Embryonic C" in The Development of C Language authored by Sir Dennis Ritchie.

Proconsul answered 18/1, 2015 at 7:32 Comment(1)
This is essentially a link-only answer. Other users have been known to say something like "While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.".Lackadaisical
A
0

For this line: char amessage[] = "now is the time";

the compiler will evaluate uses of amessage as a pointer to the start of the array holding the characters "now is the time". The compiler allocates memory for "now is the time" and initializes it with the string "now is the time". You know where that message is stored because amessage always refers to the start of that message. amessage may not be given a new value- it is not a variable, it is the name of the string "now is the time".

This line: char *pmessage = "now is the time";

declares a variable, pmessage which is initialized (given an initial value) of the starting address of the string "now is the time". Unlike amessage, pmessage can be given a new value. In this case, as in the previous case, the compiler also stores "now is the time" elsewhere in memory. For example, this will cause pmessage to point to the 'i' which begins "is the time". pmessage = pmessage + 4;

Acaulescent answered 26/8, 2009 at 20:26 Comment(0)
O
0

Here is my summary of key differences between arrays and pointers, which I made for myself:

//ATTENTION:
    //Pointer depth 1
     int    marr[]  =  {1,13,25,37,45,56};      // array is implemented as a Pointer TO THE FIRST ARRAY ELEMENT
     int*   pmarr   =  marr;                    // don't use & for assignment, because same pointer depth. Assigning Pointer = Pointer makes them equal. So pmarr points to the first ArrayElement.

     int*   point   = (marr + 1);               // ATTENTION: moves the array-pointer in memory, but by sizeof(TYPE) and not by 1 byte. The steps are equal to the type of the array-elements (here sizeof(int))

    //Pointer depth 2
     int**  ppmarr  = &pmarr;                   // use & because going one level deeper. So use the address of the pointer.

//TYPES
    //array and pointer are different, which can be seen by checking their types
    std::cout << "type of  marr is: "       << typeid(marr).name()          << std::endl;   // int*         so marr  gives a pointer to the first array element
    std::cout << "type of &marr is: "       << typeid(&marr).name()         << std::endl;   // int (*)[6]   so &marr gives a pointer to the whole array

    std::cout << "type of  pmarr is: "      << typeid(pmarr).name()         << std::endl;   // int*         so pmarr  gives a pointer to the first array element
    std::cout << "type of &pmarr is: "      << typeid(&pmarr).name()        << std::endl;   // int**        so &pmarr gives a pointer to to pointer to the first array elelemt. Because & gets us one level deeper.
Orgeat answered 25/4, 2012 at 9:42 Comment(0)
F
-2

An array is a const pointer. You cannot update its value and make it point anywhere else. While for a pointer you can do.

Fanaticism answered 26/8, 2009 at 16:35 Comment(3)
Arrays are not pointers, const or otherwise. In many contexts, the type of an array identifier will implicitly be converted from "N-element array of T" to "pointer to T", but this does not make an array a pointer.Pless
agreed.. mistake admitted.. thanks for the clarification John.Fanaticism
@JohnBode I also have misconception of thinking array as a const pointer.can you cite few more resource to clear my misconceptionStamey

© 2022 - 2024 — McMap. All rights reserved.