二维数组在内存中格式化?

在C中,我知道我可以使用下面的代码动态地在堆上分配一个二维数组:

int** someNumbers = malloc(arrayRows*sizeof(int*));

for (i = 0; i < arrayRows; i++) {
    someNumbers[i] = malloc(arrayColumns*sizeof(int));
}

显然,这实际上创建了一个指向一组单独的一维整数数组的指针数组,“系统”可以找出我的意思,当我要求:

someNumbers[4][2];

但是,当我静态声明一个二维数组,如下面的行......:

int someNumbers[ARRAY_ROWS][ARRAY_COLUMNS];

...在堆栈上创建了一个类似的结构,还是完全是另一种形式? (即它是一个指针的一维数组吗?如果不是,它是什么,以及它的引用是如何计算出来的?)

另外,当我说“系统”时,究竟是什么负责解决这个问题呢? 内核? 或者C编译器在编译时将它整理出来?


一个静态的二维数组看起来像一个数组数组 - 它只是连续地放在内存中。 数组与指针并不相同,但是因为通常可以互换使用它们,所以有时可能会引起混淆。 编译器保持正确的轨道,但是,这使得一切都很好地排队。 像你提到的那样,你必须小心静态二维数组,因为如果你试图将一个函数传递给一个带有int **参数的函数,那么就会发生不好的事情。 这里有个简单的例子:

int array1[3][2] = {{0, 1}, {2, 3}, {4, 5}};

在内存中看起来像这样:

0 1 2 3 4 5

完全相同

int array2[6] = { 0, 1, 2, 3, 4, 5 };

但是,如果您尝试将array1传递给此函数:

void function1(int **a);

你会得到一个警告(并且应用程序将无法正确访问数组):

warning: passing argument 1 of ‘function1’ from incompatible pointer type

因为2D数组与int ** 。 可以说,将数组自动衰减为指针只会“一层深”。 您需要声明该函数为:

void function2(int a[][2]);

要么

void function2(int a[3][2]);

让一切都开心。

这个相同的概念扩展到n维数组。 虽然在你的应用程序中利用这种有趣的业务通常只会让它更难理解。 所以要小心。


答案是基于C没有真正具有二维数组的想法 - 它具有数组的阵列。 当你声明这一点时:

int someNumbers[4][2];

您要求someNumbers是一个4个元素的数组,其中该数组的每个元素的类型都是int [2] (它本身是一个2 int的数组)。

难题的另一部分是数组总是在内存中连续布局。 如果您要求:

sometype_t array[4];

那么这将总是如下所示:

| sometype_t | sometype_t | sometype_t | sometype_t |

(4个sometype_t对象彼此相邻sometype_t ,两者之间没有空格)。 所以在你的someNumbers数组中,它看起来像这样:

| int [2]    | int [2]    | int [2]    | int [2]    |

而每个int [2]元素本身就是一个数组,看起来像这样:

| int        | int        |

总的来说,你会得到这个:

| int | int  | int | int  | int | int  | int | int  |

unsigned char MultiArray[5][2]={{0,1},{2,3},{4,5},{6,7},{8,9}};

在内存中等于:

unsigned char SingleArray[10]={0,1,2,3,4,5,6,7,8,9};
链接地址: http://www.djcxy.com/p/82515.html

上一篇: dimensional arrays formatted in memory?

下一篇: level static variables get allocated/initialized?