我对在堆中为二维数组分配内存的不同方法很感兴趣。
访问指向指针的指针和指向一维或多维数组的指针时,似乎使用了相同的表示法。我希望有人澄清每一个的区别和用处。他们都对吗?
第一种方法是将数组存储为指向指针的指针:
char **createTable(int r, int c) {
char **table;
int i;
char *offset;
table = malloc(r * sizeof (char *) + r * c * sizeof (char));
if (!table) return NULL;
offset = (char *) table + sizeof (char *) * r;
for (i = 0; i < r; i++) {
table[i] = offset + c * i;
}
return table;
}
这种其他方式似乎更快。我想不出像另一个函数一样将它包装在函数中的好方法。
char (*table)[c];
table = (char (*)[c]) calloc(r * c, sizeof (char));
我的理解是否正确,即使数组类似于静态指针,数组本身也可以具有多个维度?
难道我描述的第一种方式是正统方式吗?
最佳答案
不幸的是,似乎没有办法让函数返回指向正确类型化的可变长度数组的指针。你可以尝试这样的技巧:
#include <stddef.h>
#include <stdlib.h>
void* createTable_(size_t r, size_t c) {
char (*table)[c] = malloc(sizeof(char[r][c]));
/* do the intialization that you need */
return table;
}
#define createTable(R, C) ((char(*)[C])createTable_((R), (C)))
int main(int argc, char*argv[]) {
char (*table)[argc] = createTable(argc, argc);
}
该函数仅返回一个 void*
指针,宏确保正确键入。不幸的是,这样的宏必须对第二个参数求值两次,所以要小心副作用。
编辑,对于您提出的其他子问题:
我不会将指针指向模拟多维矩阵的指针方式称为“正统”,只是过时了。至少对于我所见过的大多数用法而言都是如此。
它很容易出错。你真的必须得到所有的索引计算 正确的。顺便说一句,您还可以通过使用获得更具可读性的内容
sizeof
在数组上,类似于malloc(sizeof (char*[r]) + sizeof (char[r][c]))
浪费空间,
sizeof(char*[c])
部分它的效率较低,它必须进行额外的间接计算而不是简单的索引计算。
它与其他使用大量矩阵的语言不兼容,例如 Fortran。
关于c - 指向数组的指针和指向指针的指针的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20131721/