提问人:MiguelP 提问时间:6/20/2022 最后编辑:Vlad from MoscowMiguelP 更新时间:6/20/2022 访问量:53
如何正确地将动态分配的数组用作(双)(n)维度数组?
how to correctly use a dynamically allocated array as a (bi)(nth)dimentional one?
问:
如果我使用 malloc 分配内存,我会得到一个连续的内存块:
typedef struct s_point
{
float x;
float y;
float z;
float w;
} t_point;
t_point *matrix = malloc(sizeof(t_point) * (i * j));
但是,我怎样才能做这样的事情:
matrix[x][y] = data;
在它上面?如果它只是一个指针而不是指针指针?
答:
2赞
Vlad from Moscow
6/20/2022
#1
如果您分配了一个模拟二维数组的一维数组,例如
t_point *matrix = malloc(sizeof(t_point) * (m * n));
其中是行数,是列数。
然后对于两个索引,你可以写例如m
n
i
j
for ( size_t i = 0; i < m; i++ )
{
for ( size_t j = 0; j < n; j++ )
{
matrix[i * n + j] = data;
}
}
其实写是一样的
for ( size_t i = 0; i < m * n; i++ )
{
matrix[i] = data;
}
在这两种情况下,变量 data 都必须具有 类型。否则,您需要单独分配对象的每个数据成员,例如t_point
for ( size_t i = 0; i < m * n; i++ )
{
matrix[i].x = x;
matrix[i].y = y;
matrix[i].z = z;
matrix[i].w = w;
}
2赞
tstanisl
6/20/2022
#2
您可以使用指向可变长度数组的指针:
t_point (*matrix)[n] = malloc(sizeof(t_point[m][n]));
它分配一个连续的内存块,其中各个元素可以通过 访问。请记住在不再需要内存时调用。matrix[i][j]
free(matrix)
1赞
gizlu
6/20/2022
#3
弗拉德和特斯坦尼斯尔的回答很棒。
另一种方式是支持 matrix[x][y] 语法,不使用 VLA,只分配两个连续的内存块:
t_point* buf = malloc(sizeof(t_point) * rows * cols);
t_point** matrix = malloc(sizeof(t_point*) * rows);
for(unsigned i = 0; i<rows; ++i) {
matrix[i] = buf + (i*cols);
}
// ...
free(buf);
free(matrix);
它还允许您通过重新分配指针来执行交换行之类的技巧(我不知道矩阵是否会发生这种情况,但有时使用 argv 之类的东西会很方便)。如果你不需要那个,我可能会选择弗拉德的方法
评论
0赞
MiguelP
6/20/2022
我以为做是不可能的,但我想这只是指针for(unsigned i = 0; i<rows; ++i) { matrix[i] = buf + (i*cols); }
0赞
gizlu
6/20/2022
如果你认为指针算术不直观,那么另一种方法是matrix[i] = &buf[i*cols]
评论
i,j
(i * j)
sizeof(t_point) * i * j
size_t
int
i*j
size_t
int
size_t
size_t
t_point (*matrix)[dim1][dim2][dim3];
matrix = malloc(sizeof *malloc);