Reputation: 3691
I wrote the following code:
#include <iostream>
using namespace std;
int main()
{
int a[10][10];
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
a[i][j] = i * j;
cout << *(*(a + 3) + 4) << endl;
return 0;
}
I was expecting it to print some garbage data, or a segmentation fault. What I got was 12. I tested it both in c and c++ (using gcc and g++ respectively), and I herd this works the same on VS although I haven't tested this. Why does this work, and is there a official documentation of this behavior?
Upvotes: 2
Views: 2153
Reputation: 1
The output you got is 12
and it is absolutely correct.
You did a[i][j] = i*j ;
for each element of the array. Now you print *( *(a + 3) + 4)
which is the same as a[3][4]
. As you did a[i][j] = i*j
, you now have a[3][4] = 3*4 = 12
. So it will print 12
.
Upvotes: -2
Reputation: 8333
When you want a simple answer build the complex type with typedef
s
it means:
int a[10][10];
will be:
typedef int a10[10]; //a10 is array of 10 ints
a10 a[10]; //a is array of 10 a10s
now to understand the sizes and position:
sizeof(a) = 10 * 10 * sizeof int
sizeof(a[0]) = is 10 * sizeof int
a+1 is equal to &a[1]
When you increment a pointer by 3 it is mean increment by sizeof of the type.
address of a[1] == address of a[0] + sizeof(a[0])
Therefore:
*(*(a + 3) + 4) == a[3][4]
Upvotes: 1
Reputation:
See this question for a detailed explanation.
Two dimensional arrays ([][], not **
) are contiguous in memory, as a result you can access elements using the following formula:
*((int *)array + X * NUMBER_OF_COLUMNS + Y);
i.e.
std::cout << *((int *)a + 3 * 10 + 4);
Upvotes: 2
Reputation: 145457
The declaration
int a[m][n];
means an array of m
arrays, where each such inner array is of size n
.
I remember that by remembering that the last index varies fastest.
In the expression (a + 3)
the a
reference to the outer array decays to pointer to item of that outer array. I.e. pointer to size n
array. The + 3
then adds 3 times the byte size of the inner array, to the address of the a
-as-pointer.
Dereferencing this gets you a pointer to int
.
Adding 4 to that gets you 4 positions into the inner array.
The beauty of this scheme is that it also works with "jagged arrays", arrays of pointers, because there the types are different.
The very sad thing about it is that it doesn't work well with C++ derived classes, because an array of Derived
decays to pointer to Derived
which then can be implicitly converted to pointer to Base
, which when indexed yields formal Undefined Behavior (the size of Derived
can be greater than the size of Base
).
Upvotes: 4
Reputation: 1487
You can index an array using *(arr + index) or arr[index]. They are semantically different, but functionally the same.
See this Stack Overflow discussion for more.
Difference Between *(Pointer + Index) and Pointer[]
Upvotes: 1
Reputation: 1718
*(a + b)=a[b]
you take the address of a, move it by b and take the value at the corresponding address
So *(*(a + 3) + 4)
means *(a[3]+4)
which mean a[3][4]
=12
Upvotes: 8