2

Suppose I have 2D array such as:

A[3][10];

Does it mean it is an array of 3 pointers? (from which everyone points to 1 of 10 elements)

So A is a pointer which points to 1 of 3 pointers?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 5
    [Arrays](http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c) are not pointers. – chris May 17 '14 at 16:34
  • See [How is memory allocated for an implicitly defined multidimensional array in C99](http://stackoverflow.com/questions/13850587/how-is-memory-allocated-for-an-implicitly-defined-multidimensional-array-in-c99/13850748#13850748) for an explanation; see [Two-dimensional dynamic array (`realloc()` in C)](http://stackoverflow.com/questions/20036408/two-dimensional-dynamic-array-realloc-in-c/20037199#20037199) for another. – Jonathan Leffler May 17 '14 at 17:15

2 Answers2

4

No.

It means it's an array of 3 arrays, where each of these is an array with 10 elements.

If it helps, you can think of it as one big 1D array of 30 elements with compiler support that allows you to use 2D indexing (the compiler performs the necessary calculations to turn your indexes into a flat index). In fact, this is actually how it is implemented.

Filipe Gonçalves
  • 20,783
  • 6
  • 53
  • 70
  • 2
    No it's not, it's still a single array with a bit of syntactical sugar. Your "if it helps" part is how it actually works. – BonzaiThePenguin May 17 '14 at 16:39
  • Are you sure that c++ guarantees that A[0][9] is contiguous to A[1][0] in memory? – galinette May 17 '14 at 16:40
  • 2
    @galinette, Yes, it's definitely contiguous. – chris May 17 '14 at 16:40
  • 1
    @BonzaiThePenguin It's how it's implemented (I've added this to my answer), but it is generally a good idea to abstract such details. See http://stackoverflow.com/questions/22143494/why-is-flattening-a-multidimensional-array-in-c-illegal for an example of a good question about this. – Filipe Gonçalves May 17 '14 at 16:45
  • I can't understand how **A+10 would point to the same as A[1][0] does it mean A witch is pointer to pointer is incremented or a pointer it points to – user3629811 May 17 '14 at 16:52
  • @user3629811: Note that `**A+10` is equivalent to `A[0][0] + 10`. Maybe you are thinking of `*(*A+10)` or `**(A+10)`. – Jonathan Leffler May 17 '14 at 17:11
  • Also note that C and C++ use [row-major order](http://en.wikipedia.org/wiki/Row-major_order), which is why it is an array of 3 arrays with 10 elements, and not 10 arrays of 3 elements. – John Colanduoni May 17 '14 at 17:11
2

No, it is not an array of 3 pointers. Look at the memory representation:

A[3][10]
=
|_|_|_|_|_|_|_|_|_|_|  |_|_|_|_|_|_|_|_|_|_|  |_|_|_|_|_|_|_|_|_|_|
                   ^    ^
                  px   px+4

That is, A is an array of 3 arrays which contains 10 elements each. These three arrays are contiguous in memory. That is, the element after A[0][9] is A[1][0].

And of course, as chris said, don't confuse arrays with pointers.

HelloWorld123456789
  • 5,299
  • 3
  • 23
  • 33
  • I don't think you should be stating that `A[0][10]` is the same as `A[1][0]` as the first expression has undefined behaviour. You could legitimately say 'the element after `A[0][9]` is `A[1][0]`' and not even I could take exception to that. – Jonathan Leffler May 17 '14 at 16:56
  • I understand that writing an index outside of the array is undefined behaviour. But here, `A[0][10]` boils down to `*(*A+10)` which is well inside the given space. So does it remain undefined? :) – HelloWorld123456789 May 17 '14 at 16:59
  • 2
    It is `*(*A+10)` rather than `**(A+10)`, for one thing (because `**(A+10)` is accessing wildly outside the array). But since `*A` or `A[0]` is of type 'pointer to array of 10 `int`', any use of subscript 10 is accessing out of bounds and should be avoided. While I don't know of a system where there'd be a problem, accessing an array element that is out of bounds leads to undefined behaviour and should not be taught. – Jonathan Leffler May 17 '14 at 17:03