我正在使用带有标记-Wall -std=gnu99
的gcc版本4.8.0。
我需要在C中使用malloc为连续的2D数组动态分配内存;这个事实是不可谈判的。但是,为了便于使用,我仍然希望能够使用方便的x[r][c]
表示法访问数组。这是我通过执行*array[r][c]
创建指向连续二维数组并指向数组的指针的勇敢尝试:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
size_t rows = 3, cols = 5;
printf("sizeof(int) = %li\n\n", sizeof(int));
int (*array)[rows][cols] = malloc(sizeof(int) * rows * cols);
printf("array starts at %p\n", array);
printf("sizeof(array) = %li\n", sizeof(array));
printf("sizeof(array[0][0]) = 0x%lx\n", sizeof(array[0][0]));
puts("");
unsigned short r, c;
for (r = 0; r <= rows - 1; r++) {
for (c = 0; c <= cols - 1; c++) {
printf("array[%i][%i] is at %p\n", r, c, &(*array[r][c]));
};
puts("");
};
}
虽然它在没有警告的情况下编译,但它有一些意想不到的输出:
sizeof(int) = 4
array starts at 0x16cc010
sizeof(array) = 8
sizeof(array[0][0]) = 0x14
array[0][0] is at 0x16cc010
array[0][1] is at 0x16cc024
array[0][2] is at 0x16cc038
array[0][3] is at 0x16cc04c
array[0][4] is at 0x16cc060
array[1][0] is at 0x16cc04c
array[1][1] is at 0x16cc060
array[1][2] is at 0x16cc074
array[1][3] is at 0x16cc088
array[1][4] is at 0x16cc09c
array[2][0] is at 0x16cc088
array[2][1] is at 0x16cc09c
array[2][2] is at 0x16cc0b0
array[2][3] is at 0x16cc0c4
array[2][4] is at 0x16cc0d8
我真的不明白这里发生了什么。这些元素是连续的,但它们对于整数而言太大了,并且数组太小而无法容纳所有元素。
我的数组声明是我最不确定的部分 - 我正在阅读int (*array)[rows][cols]
,因为“array
是一个指向数组的指针(带有步幅cols
)” ,但显然这是不正确的。
我到底错在了什么?
答案 0 :(得分:6)
int (*array)[cols] = malloc( sizeof *array * rows );
for (r = 0; r <= rows - 1; r++) {
for (c = 0; c <= cols - 1; c++) {
printf("array[%i][%i] is at %p\n", r, c, &array[r][c]);
这允许您将array
索引为array[i][j]
,因为array[i]
隐式取消引用指针。
要解除分配,您只需要致电
free( array );
答案 1 :(得分:3)
代码应为
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
size_t rows = 3, cols = 5;
printf("sizeof(int) = %li\n\n", sizeof(int));
int (*array)[rows][cols] = malloc(sizeof(int) * rows * cols);
printf("array starts at %p\n", array);
printf("sizeof(array) = %li\n", sizeof(*array)); // Note the *
printf("sizeof(array[0][0]) = 0x%lx\n", sizeof((*array)[0][0]));
puts("");
unsigned short r, c;
for (r = 0; r <= rows - 1; r++) {
for (c = 0; c <= cols - 1; c++) {
printf("array[%i][%i] is at %p\n", r, c, &((*array)[r][c]));
};
puts("");
};
}
因为 array 是一个指向数组[x] [y]的指针,所以你首先要取消引用它
(*array)
访问项目
(*array)[x][y]
这样你就得到了
sizeof(int) = 4
array starts at 0x12de010
sizeof(array) = 60
sizeof(array[0][0]) = 0x4
array[0][0] is at 0x12de010
array[0][1] is at 0x12de014
array[0][2] is at 0x12de018
array[0][3] is at 0x12de01c
array[0][4] is at 0x12de020
array[1][0] is at 0x12de024
array[1][1] is at 0x12de028
array[1][2] is at 0x12de02c
array[1][3] is at 0x12de030
array[1][4] is at 0x12de034
array[2][0] is at 0x12de038
array[2][1] is at 0x12de03c
array[2][2] is at 0x12de040
array[2][3] is at 0x12de044
array[2][4] is at 0x12de048
更多的是预期的值范围