Array is not pointer

With many thanks for these useful tutorials, I felt it's necessary to send this text about pointers and arrays. Unfortunately pulling out something wrong that is put in humans head is a bit difficult. So understanding the things correct and precise is very important to avoid further misconceptions.

An array is not equal to a pointer. It is a sequence of simple variables in memory.

When we write
1
2
int array[3];
array[2]=666;


C/C++ compiler doesn't see array[0] as an address to an integer value, it takes it directly as a value, exactly as same as writing
1
2
int var;
var=66;


That's obvious that "var" is not a pointer exactly as array[2] is not.

But if we use a pointer instead of an array, the face of the code is the same but compiler generates different assembly code. For example
1
2
int *ptr = new int[3];
ptr[2] = 66;


Is similar to the first code but not with the same meaning to the compiler. In the first code (second line), compiler generates code that will do the following:

1) Go two places next of the array[0] and make it equal to 666.

But in code with pointer it is:
1) Fetch the value (address) of the ptr[0].
2) Add two to it.
3) Make the value pointed by it to 66.

Actually the value of "array", "&array" and "&array[0]" is equal. But the type of "&array" is different (a memory address to an array not an array member).

Here is another example to make the article more understanding. I want to write a program that gets an integer from user, adds 4 to it and then prints out the result. Once I write it using an integer pointer and once with an integer variable.
With integer it will be:
1
2
3
4
5
6
7
#include<iostream>
main(){
    int int_input;
    cin>>int_input;
    cout<<(int_input + 4)<<endl;
    return 0;
}


And using a pointer it will be:
1
2
3
4
5
6
7
8
#include<iostream>
main(){
    int *int_ptr = new int[1];
    cin>>*int_ptr;
    cout<< (*int_ptr + 4)<<endl;
    delete(int_ptr);
    return 0;
}


Who thinks these programs are exactly the same?
Lets take a look at their assembly. For the first code with an integer it is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2212: main(){
00401000   push        ebp
00401001   mov         ebp,esp
00401003   sub         esp,44h
00401006   push        ebx
00401007   push        esi
00401008   push        edi
2213:     int int_input;
2214:     cin>>int_input;
00401009   lea         eax,[ebp-4]
0040100C   push        eax
0040100D   mov         ecx,offset cin (00414c58)
00401012   call        istream::operator>> (0040b7c0)
2215:     cout<<(int_input+4)<<endl;
00401017   push        offset endl (00401070)
0040101C   mov         ecx,dword ptr [ebp-4]
0040101F   add         ecx,4
00401022   push        ecx
00401023   mov         ecx,offset cout (00414c18)
00401028   call        ostream::operator<< (0040b3e0)
0040102D   mov         ecx,eax
0040102F   call        ostream::operator<< (00401040)
2216:     return 0;
00401034   xor         eax,eax
2217: }


And for the code with pointer it is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2212: main(){
00401000   push        ebp
00401001   mov         ebp,esp
00401003   sub         esp,4Ch
00401006   push        ebx
00401007   push        esi
00401008   push        edi
2213:     int *int_ptr = new int[1];
00401009   push        4
0040100B   call        operator new (004011b0)
00401010   add         esp,4
00401013   mov         dword ptr [ebp-8],eax
00401016   mov         eax,dword ptr [ebp-8]
00401019   mov         dword ptr [ebp-4],eax
2214:     cin>>*int_ptr;
0040101C   mov         ecx,dword ptr [ebp-4]
0040101F   push        ecx
00401020   mov         ecx,offset cin (00414c38)
00401025   call        istream::operator>> (0040b8a0)
2215:     cout<< (*int_ptr + 4)<<endl;
0040102A   push        offset endl (004010a0)
0040102F   mov         edx,dword ptr [ebp-4]
00401032   mov         eax,dword ptr [edx]
00401034   add         eax,4
00401037   push        eax
00401038   mov         ecx,offset cout (00414bf8)
0040103D   call        ostream::operator<< (0040b4c0)
00401042   mov         ecx,eax
00401044   call        ostream::operator<< (00401070)
2216:     delete(int_ptr);
00401049   mov         ecx,dword ptr [ebp-4]
0040104C   mov         dword ptr [ebp-0Ch],ecx
0040104F   mov         edx,dword ptr [ebp-0Ch]
00401052   push        edx
00401053   call        operator delete (00401120)
00401058   add         esp,4
2217:     return 0;
0040105B   xor         eax,eax
2218: }


19 lines Vs 32 lines. Therefore, you see, an integer is different to a "pointer to integer". An integer is a place of memory where an integer number is kept but an integer pointer (pointer to integer) is a place of memory where an address is saved. Compiler knows that is an address of a place of memory where an integer is held. I do not explain the assembly code since this article is for beginners and I want to keep it short.

As I said array is a sequence of variables in memory. In the example above, I concluded that a pointer is not an integer variable, so it is clear that it cannot be a sequence of them too.

Please feel free to send comments and your idea about the article.
You have a point, but you have one flaw:

ARRAYS ARE CONSTANT POINTERS.

The code
 
int array[3];

is the same as
 
int const *array=new int[3];


And the subscript operator ([]) is really a dereference operator with a shift, so
 
array[2];

is really
 
*(array+2);


Because of pointer arithmetic, adding X to an address of type T is the same as shifting that address by X*sizeof(T).

The handling of arrays as pointers is very crucial to an understanding of C. For example, you can pass an array anywhere a pointer is expected, and vice versa. A function can handle arrays, but define the type it recieves as a pointer. And since arrays are pointers (constant pointers), they are passed call by reference, meaning the array passed will be modified immediately in the calling function.

You probably have some sort of optimizing compiler that causes the phenomenon you are describing.
Topic archived. No new replies allowed.