158

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Midnight Blue
  • 5,061
  • 10
  • 41
  • 46
  • 3
    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. – Bill K Aug 26 '09 at 17:25
  • 2
    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. – Bill K Aug 26 '09 at 17:26
  • 1
    Along with the K&R (which is a great book, by the way) I'd suggest you read http://pw2.netcom.com/~tjensen/ptr/cpoint.htm - in interim. – amaterasu Aug 26 '09 at 17:45
  • See http://stackoverflow.com/a/10186799/632951 – Pacerier May 14 '15 at 13:12
  • Closing this as duplicate since we had two "canonical" FAQ threads about this very same question. – Lundin Sep 10 '15 at 11:52
  • Possibly related: http://stackoverflow.com/questions/26924257/extern-declaration-t-v-s-t – Mohit Jain Apr 27 '16 at 09:46

14 Answers14

172

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.

M.M
  • 138,810
  • 21
  • 208
  • 365
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • @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. – John Bode Mar 11 '15 at 15:42
  • @JohnBode: Just saw it right there and it confused me so i changed it, so never mind – m47h Mar 11 '15 at 15:47
  • 2
    The last line is not quite true: the behaviour is different if used as `sizeof message` or `&pmessage` . – M.M Jul 28 '15 at 06:30
  • @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? – Zen Dec 30 '15 at 07:24
  • 1
    @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. – John Bode Dec 30 '15 at 12:21
  • @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`? – Zen Jan 04 '16 at 11:07
  • 2
    @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`). – John Bode Jan 04 '16 at 12:25
  • 1
    @Zen: see [this answer](http://stackoverflow.com/questions/4607128/in-c-are-arrays-pointers-or-used-as-pointers/4608421#4608421) for more details. – John Bode Jan 04 '16 at 13:07
  • @JohnBode i am confused, is there any validity to the 2nd paragraph here then? http://c.learncodethehardway.org/book/ex15.html#explaining-pointers – Chris M Jan 25 '16 at 19:41
  • @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 `&`). – John Bode Jan 25 '16 at 20:19
  • @Zen 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. – Gab是好人 Apr 06 '16 at 12:41
  • 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. – yano Apr 19 '16 at 04:36
  • @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. – John Bode Apr 19 '16 at 12:04
  • 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 ? – Suraj Jain Dec 26 '16 at 08:46
  • @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. – John Bode Dec 26 '16 at 21:54
  • why array expression cannot be target of assignment ? You can provide link to the answer. Thanks – Suraj Jain Dec 27 '16 at 10:36
  • @SurajJain: Mainly because the language definition says so. See the [online draft](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) 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](https://www.bell-labs.com/usr/dmr/www/chist.html) (particularly the section titled "Embryonic C". – John Bode Dec 27 '16 at 13:07
  • Thank You Sir , i will do so , one favor i want from you if you can , can you please see this question http://stackoverflow.com/questions/34826036/confused-about-pointer-dereferencing , and confirm if the answer is correct. It is bugging me for a year now. – Suraj Jain Dec 27 '16 at 13:52
  • @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. – John Bode Dec 27 '16 at 14:41
  • Doesn't Char get promoted to integer , becasue printf is a varadic function. And in promotion value stays same. – Suraj Jain Dec 27 '16 at 14:48
  • http://stackoverflow.com/questions/1255775/default-argument-promotions-in-c-function-calls – Suraj Jain Dec 27 '16 at 14:50
  • @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. – John Bode Dec 27 '16 at 15:14
  • If they do get converted what is the problem using %d . – Suraj Jain Dec 27 '16 at 15:39
  • This Question has exact same thing as mine , please see this http://stackoverflow.com/a/35496066/5473170 If they do get converted what is the problem using %d . – Suraj Jain Dec 27 '16 at 16:26
117

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.

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

Walt W
  • 3,261
  • 3
  • 30
  • 37
  • 7
    While true, this is hardly the biggest difference. What's the difference between &amessage and &pmessage, for example? – Mark Ransom Aug 26 '09 at 16:12
  • 2
    `&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`. – GManNickG Aug 26 '09 at 16:24
  • 5
    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). – Pavel Minaev Aug 26 '09 at 16:24
  • Weird, I guess C does do that. I figured &amessage would be invalid as amessage is resolved to a code-constant pointer . . . – Walt W Aug 26 '09 at 16:27
  • 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. – Walt W Aug 26 '09 at 16:29
  • 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... – Bill K Aug 26 '09 at 17:27
  • 1
    @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. – Walt W Aug 26 '09 at 17:42
  • `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. – Johannes Schaub - litb Aug 26 '09 at 17:44
  • 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. – Johannes Schaub - litb Aug 26 '09 at 17:46
  • @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)? – Walt W Aug 26 '09 at 17:46
  • er, check the edit now, is that more correct? – Walt W Aug 26 '09 at 17:48
  • This looks like a community wiki entry now... – Adam W Aug 26 '09 at 17:50
  • @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) – Johannes Schaub - litb Aug 26 '09 at 17:59
  • "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. – M.M Jul 28 '15 at 06:19
  • 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 ? – Suraj Jain Dec 26 '16 at 08:26
  • @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. – Walt W Dec 29 '16 at 18:15
  • I learned that array name cannot be used as l value that it why it doesn't work.?? – Suraj Jain Dec 29 '16 at 18:29
  • No, I don't believe that is why. See previous answer. – Walt W Jan 06 '17 at 22:23
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.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 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 http://stackoverflow.com/a/41349954/5473170 – Suraj Jain Dec 28 '16 at 05:13
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.

Norman Ramsey
  • 198,648
  • 61
  • 360
  • 533
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tamás Szelei
  • 23,169
  • 18
  • 105
  • 180
  • 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. – Nicolas Miari Dec 14 '14 at 14:24
4

A pointer is just a variable that holds a memory address. Notice that you are playinf with "string literals" which is another issue. Differences 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");

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


/* Hope it was useful*/
return 0;
}
Sergio
  • 41
  • 2
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
Graphics Noob
  • 9,790
  • 11
  • 46
  • 44
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.

M.M
  • 138,810
  • 21
  • 208
  • 365
Dan Moulding
  • 211,373
  • 23
  • 97
  • 98
  • 1
    That's wrong. The array holds a copy of the string literal - it's not the same array. – Johannes Schaub - litb Aug 26 '09 at 18:09
  • 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. – Dan Moulding Aug 26 '09 at 18:23
  • Now it makes much sense to me. Thanks for the further explanation! – Johannes Schaub - litb Aug 26 '09 at 18:53
  • @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! – M.M Jul 28 '15 at 06:27
  • @M.M how is `&amessage` same as `&amessage[0] ` – Suraj Jain Dec 27 '16 at 02:52
  • @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] ` – Suraj Jain Dec 27 '16 at 03:08
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

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
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
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').

benzaita
  • 12,869
  • 3
  • 20
  • 22
1

The above 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.

abcoep
  • 577
  • 9
  • 14
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;

-1

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.
Skip
  • 6,240
  • 11
  • 67
  • 117
-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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mkamthan
  • 2,331
  • 3
  • 17
  • 23
  • 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. – John Bode Aug 27 '09 at 00:59
  • agreed.. mistake admitted.. thanks for the clarification John. – mkamthan Aug 27 '09 at 15:28
  • @JohnBode I also have misconception of thinking array as a const pointer.can you cite few more resource to clear my misconception – akashchandrakar Nov 17 '14 at 21:44