C中的动态多维数组

在c中读了几篇关于多维数组动态内存分配的文章,我遇到了以下代码片段:( 文章链接)

#define COLS 5 int (*rptr)[COLS]; int main(void) { int nrows = 10; int row, col; rptr = malloc(nrows * COLS * sizeof(int)); for (row = 0; row < nrows; row++) for (col = 0; col < COLS; col++) rptr[row][col] = 17; return 0; } 

这里,multidimensinal数组定义为int(* rptr)[COLS],然后动态链接到malloc(nrows * COLS * sizeof(int))。

现在问题是指向如何工作,例如:如果指向地址从100,101,102开始……等等

(假设int为简单起见需要1个字节)

 rptr[0] points to -> 100 rptr[1] points to -> 105 

一旦执行malloc(nrows * COLS * sizeof(int)),编译器是否会根据列大小在内部相应地链接地址?

谢谢

考虑这个普通的数组分配:

 int* a = malloc(sizeof(int) * 10); 

类型“int *”当然是指向int的指针,而sizeof(* a)== sizeof(int)。 当我们做[3]时,这将转换为:

 *(a + 3) 

其中(假设sizeof(long)== sizeof(void *))取消引用地址:

 (long)a + 3*sizeof(*a) == (long)a + 3*sizeof(int) 

考虑示例代码的方法是类型“int(* rptr)[COLS]”是指向大小为COLS的(静态,一维)int数组的指针。 换句话说,sizeof(* rptr)== COLS * sizeof(int)。 但是,就像“int *”一样,我们可以分配这些固定大小的一维数组对象的数组。 索引“rptr [row]”转换为:

 *(rptr + row) 

取消引用地址:

 (long)rptr + row*sizeof(*rptr) == (long)rptr + row*COLS*sizeof(int) 

结果类型为“int [COLS]”,因此可以通过“[col]”再次索引。 地址计算最终正是您想要的:

 (long)rptr + row*COLS*sizeof(int) + col*sizeof(int) 

此解决方案在http://c-faq.com/aryptr/dynmuldimary.html中提及,并且仅在编译时修复列数(或通常除第一维之外的所有列)时才有效。 随着维度数量的增加,语法会变得有点混乱。 如果您需要在运行时动态确定多个维度,请参阅该页面以了解其他策略。