假设我写了这个片段:
#include<stdio.h>
int main()
{
int elements;
printf("enter number of elements for arrayn");
scanf("%d", &elements);
int arr[elements];
}
我按malloc
为数组动态分配内存,除了malloc
堆中分配内存之外,还有什么区别?在第一种情况下,编译时将分配多少内存?
主要有两点:
-
malloc
通常会将内存对齐到sizeof(max_align_t)
字节,而堆栈上的分配则不会。
堆栈 上的分配可能会导致堆栈溢出,而使用
malloc
进行分配应在内存过度使用时返回错误。您可以返回由
malloc
返回的指针,但不能返回堆栈上分配的指针。
这称为可变长度数组。 它们与其他局部变量位于同一位置,通常在堆栈上,并且在运行时为它们留出空间。
如果要使用sizeof(arr)
,这将是在运行时而不是编译时计算sizeof
表达式的少数实例之一。
可变长度数组 (VLA(是 C99 标准引入的一项功能,由 C11 标准可选。malloc
分配和VLA之间的主要区别在于,返回通过从函数调用malloc
获得的指针是正常的,但从函数返回本地VLA(或者更准确地说,返回指向数组初始元素的指针(几乎总是错误的。如果在调用函数中使用该指针,则这是未定义的行为。比较这两个函数:
int *f(int n)
{
int arr[n]; // VLA
/* Do some stuff */
return arr; // WRONG: returns address of local variable
}
int *g(int n)
{
int *arr = malloc(n * sizeof *arr);
if (arr == NULL) {
/* Memory allocation failed. Treat accordingly */
}
/* Do some stuff */
return arr;
}
另一个区别是;无法检测大型 VLA 分配上的错误,但可以通过检查指针NULL
来检测malloc
分配。