使用malloc分配具有不同行长的多维数组


68

我有以下C代码:

效果很好。但是如果我有以下内容:

其中的每个元素b都有不同的长度。

怎么可能做b和我一样的事情a;即下面的代码将保持正确?

Answers:


79

首先,您需要分配指针数组,例如char **c = malloc( N * sizeof( char* )),然后malloc可能在循环中通过对的单独调用来分配每一行:

如果您知道元素的总数(例如N*M),则可以一次分配。


2
如果您在单个操作中分配N M个字节,那么您将手动填充所有c [i]:c [i] = p + M i;
Tadeusz A.Kadłubowski09年

2
这取决于c的类型-如果它是char **,则是,如果它是char *,则索引更改:element [i] [j]〜c [i * M + j]。
尼古拉·费迪索夫

1
@Nikolai N Fetissov,代码中有很多malloc,如何将其全部释放?通过还使用循环?
e19293001 2011年

2
@ e19293001是的,free每个一个malloc。您必须遍历char*变量以释放它们,然后释放char**
erickrf 2012年

我在一本书中看到了同样的内容,上面写着“ ...内存不保证是连续的。”?
dud3

49

动态分配类型T的NxM数组的典型形式是

如果数组的每个元素的长度都不同,则将M替换为该元素的适当长度;例如


如果我拥有将要拥有的int总数,但是没有多少个整数放入每个数组中,我应该如何进行?
Dietbacon 2014年

答案很明确,谢谢!您是否也可以添加说明以哪种顺序正确free分配内存?
Kagaratsch '18

2
@Kagaratsch:通常,以您分配的相反顺序释放-即a[i]先释放每个,然后释放a
John Bode

29

的等效内存分配char a[10][20]如下。

我希望这看起来很容易理解。


10

另一种方法是分配一个连续的内存块,其中包括用于行指针的头块和用于在行中存储实际数据的主体块。然后只需通过按行将主体中的内存地址分配给标头中的指针来标记内存。它看起来像如下:

这种方法的优点是可以释放内存,并且可以使用类似数组的符号来访问所得2D数组的元素。


2
需要注意的是:与其他每次分配一行的方法不同,此解决方案通常在缓存一致性方面表现更好,因为保证了各个行是连续的,并且可能导致矩阵的各个部分分散整个高度分散的堆中。
Max DeLiso 2014年

4
不幸的是,这还具有不能保证非指针大小类型对齐的副作用。例如:如果系统具有32位指针和64位双精度数且行数为奇数,则会在的未对齐边界处开始双精度数行的第一列double。考虑到这一点非常重要,因为由于不正确的数据对齐,它很容易导致总线错误。通用解决方案应确保数据行从8字节的边界开始,分配额外的分配空间,并在将行指针分配给主指针段时进行相应调整。
WhozCraig 2014年

@DmitryAleks:您要在哪里申报columnSizes[]
user2284570 2015年

3

如果b中的每个元素都有不同的长度,那么您需要执行以下操作:


1
它不会为char *指针的一维数组分配内存。
Tadeusz A.Kadłubowski09年

2

我认为最好采用两步法,因为c 2-d数组正好与数组数组相同。第一步是分配一个数组,然后循环遍历为每个列分配数组。 本文提供了详细的信息。


1

二维阵列动态内存分配


0

malloc不在特定边界上分配,因此必须假定它在字节边界上分配。

如果将返回的指针转换为任何其他类型,则不能使用它,因为访问该指针可能会导致CPU违反内存访问,并且应用程序将立即关闭。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.