C 存储2d阵列所需的内存

C 存储2d阵列所需的内存,c,multidimensional-array,dynamic-memory-allocation,C,Multidimensional Array,Dynamic Memory Allocation,我一直在读关于C语言中2d内存分配的文章。在第四个例子中,他们设置了 len = sizeof(int *) * r + sizeof(int) * c * r; 直觉上,我认为最后一项已经足够了,因为数组具有c*r维度。有谁能向我解释为什么第一学期是必要的吗 len = sizeof(int *) * r + sizeof(int) * c * r; 您需要存储所有行的所有指针: lenRow = sizeof(int *) * r lenArray = sizeof(int) * c

我一直在读关于C语言中2d内存分配的文章。在第四个例子中,他们设置了

len = sizeof(int *) * r + sizeof(int) * c * r;
直觉上,我认为最后一项已经足够了,因为数组具有c*r维度。有谁能向我解释为什么第一学期是必要的吗

len = sizeof(int *) * r + sizeof(int) * c * r;
您需要存储所有行的所有指针:

lenRow = sizeof(int *) * r
lenArray = sizeof(int) * c * r
您需要存储2d阵列的所有数据:

lenRow = sizeof(int *) * r
lenArray = sizeof(int) * c * r
lenRow和lenArray之和是分配中所需的总大小

保留数组中的第一个数据以放置指针

// ptr is now pointing to the first element in of 2D array
ptr = (int *)(arr + r);

// for loop to point rows pointer to appropriate location in 2D array
for(i = 0; i < r; i++)
    arr[i] = (ptr + c * i);
//ptr现在指向2D数组中的第一个元素
ptr=(int*)(arr+r);
//对于循环指向行,指针指向二维数组中的适当位置
对于(i=0;i

Done

代码实现了一个二维数组作为指向
int
的指针,因此它为指向
int
r
指针数组和
r
c
int
对象分配空间。(这通常是不好的做法,因为使用指向指针的指针通常具有不好的性能。在支持可变长度数组的C实现中,它们通常是更好的选择。否则,将索引计算到一维数组中,就像使用
i*C+j
映射索引
[i][j]
到一维,性能更好。)

因此,指针需要
sizeof(int*)*r
字节,对象需要
sizeof(int)*c*r
字节。但是,也可能需要在这些对象之间填充,以确保
int
对象正确对齐。在常见的C实现中,所需的填充量为零,因为
int
的对齐方式通常小于或等于
int*
的对齐方式。但是,在C标准的要求范围内,它可以是非零的。因此,要分配的适当内存量是:

sizeof (int *) * r + _Alignof (int) - 1 - (sizeof (int *) * r - 1) % _Alignof (int) + sizeof (int) * c * r

在这种情况下,
\u Alignof(int)-1
是我们可能需要填充的最大字节数(如果我们在设计的倍数后只结束一个字节,我们需要添加
\u Alignof(int)-1
以获得下一个倍数),以及
(sizeof(int*)*r-1)%\u Alignof(int)
int*
的空间超过一个字节的字节数,模
\u Alignof(int)
,因此从最大值中减去该值就可以得到下一个倍数所需的字节数。

与第三个示例类似,但所有malloc调用都合并为一个调用
sizeof(int*)*r
+
r
sizeof(int)*c
然后手动拆分。该页面也没有提到最佳方法
int(*arr)[c]=malloc(r*sizeof*arr)。该代码不分配2D数组(也称为数组的数组)。代码使用
r
int指针分配数组,使用
r*c
int分配内存块。通过正确初始化
r
指针,可以像二维数组一样访问分配的内存。但还是。。。这不是2Darray@mch谢谢你,这是有道理的!我不能投你一票,但这绝对是有帮助的。您建议的方法看起来非常圆滑、简洁,而且更直观。再次感谢您。@4386427这似乎超出了我所读文章的范围,但如果您有一些资料可以参考我,我非常愿意阅读。@hodjafrapjort这可能会有帮助: