开发者

Memory map for a 2D array in C

开发者 https://www.devze.com 2023-03-19 16:39 出处:网络
Do you think what this discussion about memory-map of 2D array is correct? Especially this photo? Can you explain the theory?

Do you think what this discussion about memory-map of 2D array is correct? Especially this photo? Can you explain the theory?

Suppose we declare a 2D array in C like this:

int arr[3][3]={10, 20, 30, 40, 50, 60, 70, 80, 90};

Now, according to this discussion, the memo开发者_如何学Cry would be arranged like the following:

Memory map for a 2D array in C

Now, I have written the following code to test this theory:

#include <stdio.h>

main()
{
    int arr[3][3]={10, 20, 30, 40, 50, 60, 70, 80, 90};
    printf("      arr==%d\n", arr);
    printf("  &arr[0]==%d\n", &arr[0]);
    printf("   arr[0]==%d\n", arr[0]);
    printf("&arr[0][0]=%d\n", &arr[0][0]);
    printf(" arr[0][0]=%d\n", arr[0][0]);
}
/*
Output:
========
      arr ==1245028
  &arr[0] ==1245028
   arr[0] ==1245028
&arr[0][0]==1245028
 arr[0][0]==10
Press any key to continue...
*/

Why the first 4 outputs are same?


See my question here.

That is not the way you access information about 2-d arrays. In fact, you can just think of them as 1-d, where you multiply and add the indices in a special way.

e.g.

int x[10] = {0,1,2,3,4,5,6,7,8,9};
int y[2][5] = {{0,1,2,3,4},{5,6,7,8,9}};

These are formatted exactly the same in memory, and they look like this:

|0|1|2|3|4|5|6|7|8|9|

So to get the 8 element, you can either ask for x[8], or y[1][3].

For the second way, you can think of it as (1 * 5) + 3.

This is why your first 4 were the same. You have:

  • arr: this is the address of the start of the array
  • arr[0]: this is address of the start of the first sub-array, which is the same as the start of the overall array
  • &arr[0][0]: this is the address of first element of the first sub-array, also the start of the overall array
  • arr[0][0]: this is the value stored in the first element of the first sub-array.


Your code just uses a plain multidimensional array, but the image describes an array of pointers, like the kind you usually make when malloc-ing things.

A multidimensional array is basically just a normal, flattened, array (in memory) with some extra syntatic sugar for accessing. So while it is possible to get a pointer from arr[i], there isn't an extra "variable" just to store this, as happens in your image.

To correct the image, remove the parts with the arr[0], arr[1]... and change the value of arr to 1245039 (the same as &arr[0][0]).


The first four outputs are the same why of obtaining the address of the first element in the array, i.e. &arr[0][0]. The last output is its content.


well, as far as i recall, in C++ (and i think C, although that's not my forte) a 2d array declared as Values[][] is generally (don't know if always) implemented as an array of C-style arrays. however, when you declare them on the stack (e.g. a local variable), i believe the memory formatting is different.

so, when you declare a local variable everything is laid out as if it were just a 1d array, and you get things laid out such that you can actually cast to a pointer and then access as a 1D array.(!) however, it still is recognized the same way as a normal 2D array within the scope of the declaration, and possibly if you pass to a parameter which is declared with the [] notation.

but, if you allocate one of these on the heap (e.g. global or static or via new), the story is different. now, the memory is laid out as an actual array of arrays, and so the actual results of the memory locations you index if you cast to a 1D array and index is now going to be pointers instead.

i verified my recall by doing the following: i created int HeapArray[3][3]; as a global, and int StackArray[3][3]; as a local (both with initializers of { { 10, 20, 30 }, {40, 50, 60}, {70, 80, 90 } }). inside my function i cast both of them to an int pointer, int* ptrHeapArray = (int*)HeapArray; and int* ptrStackArray = (int*)StackArray; and then looked at the return value of the 0th element of each.

[edit: whoops, i had them reversed; fixed now]

ptrStackArray[0] was equal to 10

ptrHeapArray[0] was equal to a pointer to int[3];

so i think my limited recall is accurate. :) hope this helps!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号