何时使用具有最大值的数组以及何时使用malloc

何时使用具有最大值的数组以及何时使用malloc,c,arrays,C,Arrays,在用C编写项目时,我总是很矛盾:是使用具有预定义长度且具有最大可能值的数组,还是创建具有实际数据长度的动态数组 int a1[MAXIMUM_ALLOWED_VALUES]; int *a2; // will be malloced according to the data length 我知道如果数据长度小于最大值,a1将浪费空间,而a2则更难管理 使用每种方法的规则是什么?如何选择?没有硬性规则,但任何自动变量(如int a1[1000])都会占用堆栈上的空间,任何分配的空间都会占用

在用C编写项目时,我总是很矛盾:是使用具有预定义长度且具有最大可能值的数组,还是创建具有实际数据长度的动态数组

int a1[MAXIMUM_ALLOWED_VALUES];

int *a2;  // will be malloced according to the data length
我知道如果数据长度小于最大值,a1将浪费空间,而a2则更难管理


使用每种方法的规则是什么?如何选择?

没有硬性规则,但任何自动变量(如int a1[1000])都会占用堆栈上的空间,任何分配的空间都会占用堆上的空间

通常,linux上的堆栈空间有限,您可以使用ulimit-s获得它,堆大约是您的RAM


这取决于您是否认为您的程序将占用不必要的堆栈空间,并且因为MAX太大而不得不使用int*a2而不是int a1[MAX]的情况并不罕见。

最简单的答案是这取决于具体情况。 这取决于许多因素和用例。作为一个在低内存占用微控制器上工作的人,我更倾向于静态内存分配

没有硬性规定,但如果您正在为较小的内存占用平台开发一些东西,那么您可能会想到您需要的最坏情况的内存。除非您没有近似的内存预算,否则整个动态内存分配情况是有争议的。 一般认为,对于内存占用有限的小型嵌入式系统,静态内存分配总是比动态内存分配更安全,因为这样做不值得。因此,您必须关心动态分配了多少内存,是否存在内存泄漏的可能性,因为典型的基于C/C++的系统不会有垃圾收集器这样的机制。想想系统无法分配请求的内存宽度的情况?还有一个额外的错误处理。嵌入式系统很好,它们中的大多数(如果不是全部的话)都有固定的、预期的内存需求

这可能被解释为有利于静态内存分配,控制内存是一种更好的方法。然而,从另一个角度来看,CPU需要花费时间来执行动态分配-取消分配,尽管如此,它还是增加了开销。这对于实时系统来说是一个额外的问题,例如,典型的实时系统通常没有专用的内存管理单元。动态内存分配最常见的问题是内存碎片。较小内存占用上的碎片是另一个幽灵替代器

考虑一下这个w.r.t动态内存分配, 比如说,堆的宽度是1024字节

尚未分配内存:可用内存:1024字节

 ______________________________________________________________
|                                                              |
|                                                              |
|______________________________________________________________|
|<---------------------------- Heap -------------------------->|
现在,可用内存:1024字节。我成功地为一个数组arr400调用了另外400个字节,假设它是从1024个字节的第400个位置开始的

 ______________________________________________________________
|              |            |                      |           |
|    arr200    |            |        arr400        |           |
|______________|____________|______________________|___________|
|<---------------------------- Heap -------------------------->|

现在,可用内存:424字节。但是我的下一个malloc最多只能产生224个字节,尽管在设计解决方案时使用了精确的内存近似,但我们注定要失败

没有硬性规定。有意义时使用a1,有意义时使用a2。避免堆栈上的大型数组,记住malloc也有内存开销。当定义好最大大小时,我更喜欢a1,比如名称、地址、URI等等。减少工作上的麻烦。就我个人而言,我经常定义一个结构名{char val[name_MAX+1];};以及一些内联函数来处理名称\u t。通过这种方式,很难在混合不同字符串类型name\t array\t、uri\t等的情况下产生意外错误。此外,函数可以返回name\t对象,这非常方便。如果已知的最大值是固定的,并且不太大,则可以使用静态数组。在大多数情况下,最大值是假设的,人们选择不可能达到的值。
 ______________________________________________________________
|              |            |                      |           |
|    arr200    |            |        arr400        |           |
|______________|____________|______________________|___________|
|<---------------------------- Heap -------------------------->|