malloc还是普通的数组定义?

时间:2012-06-28 08:44:35

标签: c arrays malloc

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

我无法理解:

之间的区别
int a[3]={1,2,3}
int array[sizeof(a)/sizeof(int)]

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

4 个答案:

答案 0 :(得分:14)

通常,在以下情况下使用malloc()

  • 数组太大而无法放在堆栈上
  • 阵列的生命周期必须比创建它的范围更长

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

答案 1 :(得分:5)

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

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

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

在这两种情况下,每个数组中的元素数量是一个编译时常量:3显然是一个常量,而sizeof(a)/sizeof(int)可以在编译时计算,因为{{1}的大小都是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)分配了数组的内存一样。

答案 2 :(得分: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;

答案 3 :(得分:1)

你的代码很奇怪。

标题中问题的答案可能类似于“当您需要非常短暂的数据时使用自动分配的数组,使用malloc()进行堆分配”。但是很难确定答案,这在很大程度上取决于具体情况。

不确定为什么你首先显示一个数组,然后是另一个数组试图从第一个数组计算它的长度,最后一个malloc()调用尝试做同样的事情。

通常,您可以了解所需元素的数量,而不是想要模仿其大小的现有数组。

第二行更好:

int array[sizeof a / sizeof *a];

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

此外,第三行应该是:

a

对于array = malloc(sizeof a); 参数和no need to cast malloc()'s return value,不需要太聪明(特别是因为你弄错了)。