如何正确地将动态分配的数组用作(双)(n)维度数组?

how to correctly use a dynamically allocated array as a (bi)(nth)dimentional one?

提问人:MiguelP 提问时间:6/20/2022 最后编辑:Vlad from MoscowMiguelP 更新时间:6/20/2022 访问量:53

问:

如果我使用 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;

在它上面?如果它只是一个指针而不是指针指针?

数组 C 多维数组 malloc

评论

0赞 chux - Reinstate Monica 6/20/2022
是什么类型i,j
0赞 MiguelP 6/20/2022
@chux-ReinstateMonica int 为什么?
0赞 chux - Reinstate Monica 6/20/2022
请注意,当不这样做时可能会溢出,因为乘法是使用数学而不是 的乘法完成的。 数学通常更宽,有时比 宽得多。当然,其他代码也需要保护。提示:最好使用数学来编制数组索引。保重,是一些无符号的类型。(i * j)sizeof(t_point) * i * jsize_tinti*jsize_tintsize_tsize_t
0赞 chux - Reinstate Monica 6/20/2022
如果您有一个指向 n 次数组的指针,则使用 .t_point (*matrix)[dim1][dim2][dim3];matrix = malloc(sizeof *malloc);

答:

2赞 Vlad from Moscow 6/20/2022 #1

如果您分配了一个模拟二维数组的一维数组,例如

t_point *matrix = malloc(sizeof(t_point) * (m * n));

其中是行数,是列数。 然后对于两个索引,你可以写例如mnij

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]