Because C/C++ lets you to do so. But the mechanism to calculate effective address is a little bit different. For static array: executive file knows the address of var[0] and knows the size of each array element. So Effective Address = Address of var[0] + (12 * sizeof(var[0]) )
But for the pointer and dynamic array: executive file does not know the address of the dynamic array's first element (var[0]) in the memory. But it knows the address of a pointer (pointer is a variable that holds a memory address) that points to the first element of the dynamic array. The formula for calculating effective address is:
Effective Address = Address of var[0] + (12 * sizeof(var[0]) )
So where is the difference? It is in getting address of var[0].
In the case of pointer, Executive file does not know the address of var[0], it needs to look into the pointer to find that address. Look at the assembly codes for int a = var[12]:
For static array:
Code:
mov eax,dword ptr [ebp-20h] //20h = 32
mov dword ptr [ebp-54h],eax //54h = 84
For dynamic array:
Code:
mov eax,dword ptr [ebp-4]
mov ecx,dword ptr [eax+30h] //30h = 48
mov dword ptr [ebp-8],ecx
ebp is the start of stack and have the value of 1245040. The stack will be filled like the picture:<<>>
In our example program we have only one array and a variable 'a' in the stack. The first element of array is placed in the address ebp – 80 = ebp - (4 * 20) (Each integer is four bytes and the array has twenty elements) address of variable 'a' is ebp - "size of the whole array" - "size of int" = ebp - 80 – 4 = ebp - 84
For calculating address of var[12] we should subtract 48 from 80 that gives 32 and then minus it from ebp. So it is ebp – 32.
[] means "the value that this address points to" it is like dereferencing sign in C/C++ (astrix "*").
First line says place the value which is placed in memory address "ebp - 32" in the eax register (Registers are some small memories in the CPU used for proccessing operations).
Now we have var[12] in eax. Then it moves it into variable 'a': In the second line as it says place the value of eax in the memory address "ebp - 84" which is the address of 'a' as we calculated above.
Now for the dynamic array case 'a' and 'var' are two local variables placed in the stack both are 32 bits (= 4 bytes). 'a' is an integer and 'var' is a pointer. In my compiler int is four bytes and in my machine pointers are 4 bytes too.
The var is the first variable in the stack. Its address is "ebp - 4". The 'a' is placed right after it so has the address "ebp – 8". In the first line, it picks the value of the var (ebp - 4) which is the address of allocated memory returned by new operator. Then puts the address in eax register. After this it needs the value of var[12]. To calculate its address, it adds 48 to eax. Which means adding 48 (= 4 * 12) to address of allocated memory ([ebp - 4]). In the second line it puts the value of var[12] in ecx register. At last in the third line it puts the value of ecx in the 'a' (which has the address ebp - 8).
You may ask why in the case of static array it subtract the offset from base address while for dynamic array it adds the offset to base address. Well, this is because of the way that stack and heap memory are managed and is out of scope.
The static arrays are placed in the stack portion of memory while dynamic arrays are in the heap portion.