多维数组是如何在内存中格式化的?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (14)

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

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

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

很明显,这实际上创建了一个指向一组独立的一维整数数组的一维指针数组,“系统”可以在我请求时找出我的意思:

someNumbers[4][2];

但是,当我静态地声明一个2D数组时,如下面一行所示...:

int someNumbers[ARRAY_ROWS][ARRAY_COLUMNS];

.

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

提问于
用户回答回答于

静态的二维数组看起来就像数组--它只是在内存中连续排列。数组与指针不是一回事,但是由于经常可以交替地使用它们,所以有时会变得很混乱。不过,编译器能够正确地跟踪,这使得所有的事情都很好地排列起来。确实需要像前面提到的那样小心处理静态2D数组,因为如果试图将一个数组传递给一个函数,则需要使用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组成的数组。ints)。

这个难题的另一部分是数组总是在内存中连续排列。如果你要求:

sometype_t array[4];

那就永远是这样的:

| sometype_t | sometype_t | sometype_t | sometype_t |

(4sometype_t在彼此之间没有空格的情况下排列在一起的对象)。所以在你的someNumbers数组,看起来如下:

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

每一个int [2]元素本身就是一个数组,如下所示:

| int        | int        |

所以总的来说,你可以看到:

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

扫码关注云+社区