6

我什么时候应该在 C 中使用 malloc 而不是普通的数组定义?

我无法理解以下之间的区别:

int a[3]={1,2,3}
int array[sizeof(a)/sizeof(int)]

和:

array=(int *)malloc(sizeof(int)*sizeof(a));
4

4 回答 4

19

一般来说,在以下情况下使用malloc()

  • 数组太大而无法放入堆栈
  • 数组的生命周期必须超过创建它的范围

否则,使用堆栈分配的数组。

于 2012-06-28T08:50:38.073 回答
6
int a[3]={1,2,3}
int array[sizeof(a)/sizeof(int)]

如果用作局部变量,则两者都aarray在堆栈上分配。堆栈分配有其优点和缺点:

  • 亲:它非常快 - 只需要一次寄存器减法操作来创建堆栈空间和一次寄存器加法操作来回收它
  • 缺点:堆栈大小通常是有限的(并且在 Windows 上的链接时也固定)

在这两种情况下,每个数组中的元素数量都是编译时常量:3显然是一个常量,而sizeof(a)/sizeof(int)可以在编译时计算,因为在声明时,大小a和大小int都是已知的array

当元素的数量仅在运行时已知或数组的大小太大而无法安全地放入堆栈空间时,则使用堆分配:

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

正如已经指出的那样,这应该是malloc(sizeof(a))因为 的大小a已经是它占用的字节数而不是元素的数量,因此sizeof(int)不需要额外的乘法。

堆分配和释放是相对昂贵的操作(与堆栈分配相比),这应该仔细权衡它提供的好处,例如在紧密循环中被多次调用的代码中。

现代 C 编译器支持 C 标准的 C99 版本,该版本引入了所谓的可变长度数组(或 VLA),它类似于其他语言中可用的类似功能。VLA 的大小是在运行时指定的,如下例所示:

void func(int n)
{
   int array[n];
   ...
}

array仍然在堆栈上分配,就好像数组的内存已通过调用alloca(3).

于 2012-06-28T10:21:40.337 回答
2

如果您不希望数组具有固定大小,则肯定必须使用malloc() 。根据您要执行的操作,您可能事先不知道给定任务需要多少内存,或者您可能需要在运行时动态调整数组大小,例如,如果有更多数据,您可能会扩大它进来。后者可以使用realloc()来完成而不会丢失数据。

而不是像在原始帖子中那样初始化数组,您应该只初始化一个指向整数的指针。

int* array; // this variable will just contain the addresse of an integer sized block in memory
int length = 5; // how long do you want your array to be;

array = malloc(sizeof(int) * length); // this allocates the memory needed for your array and sets the pointer created above to first block of that region;

int newLength = 10;
array = realloc(array, sizeof(int) * newLength); // increase the size of the array while leaving its contents intact;
于 2012-06-28T09:08:20.003 回答
1

你的代码很奇怪。

标题中问题的答案可能类似于“当您需要相当少量的短期数据时使用自动分配的数组,堆分配malloc()用于其他任何事情”。但是很难确定一个确切的答案,这在很大程度上取决于情况。

不知道为什么首先显示一个数组,然后是另一个尝试从第一个数组计算其长度的数组,最后是一个malloc()尝试执行相同操作的调用。

通常,您知道所需元素的数量,而不是要模拟其大小的现有数组。

第二行更好:

int array[sizeof a / sizeof *a];

无需重复对 的类型的依赖a,上面将定义array为与数组int具有相同数量元素的数组a。请注意,这仅在a确实是数组时才有效。

此外,第三行应该是:

array = malloc(sizeof a);

不需要对参数太聪明(尤其是因为你弄错了)sizeof也不需要强制转换malloc()的返回值

于 2012-06-28T08:47:38.363 回答