[英]Dynamic memory allocation in C for variable length arrays
在 C 中用 calloc 与“普通”数组声明实例化可变长度数组什么时候更好?
考虑“数组声明”方法:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int n = atoi(argv[1]);
int x[n];
for(int i = 1; i < n; i++){
x[i] = i;
printf("%i", x[i]);
printf("\n");
}
return 0;
}
与 calloc 方法相比:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int n = atoi(argv[1]);
int * x = (int*) calloc(n, sizeof(int));
for(int i = 1; i < n; i++){
x[i] = i;
printf("%i", x[i]);
printf("\n");
}
return 0;
}
你应该总是使用其中一个吗? 一个比另一个快(例如堆栈与堆分配的 bc)? 一个比另一个风险更大吗?
int x[n];
包括 VLA 在内的自动存储持续时间对象(通过大多数现代实现)分配在堆栈上。 如果将较大的对象分配在堆栈上(三个最重要的),则会出现一些问题:
巨大的区别在于,在第一个示例中,该数组仅在包含 function 的生命周期内存在,但在第二个示例中,它会一直存在直到其发布。
在您的示例中,只有主要的 function 所以差异并不重要,但在实际应用中它很重要。
其次,第一个可以有多大的限制,因为它分配在堆栈上,这是一个有限的资源。 (试试看,使数组有 100 万个元素)。 第二种情况仅受堆大小的限制,通常要大得多
问这两个问题“我的数组大小适合堆栈吗?” 和“我需要这个阵列多长时间(程序或 function 寿命)?” .
静态分配的 arrays 在 function 的生命周期内存在。 返回时,function 堆栈(以及声明为该 function 的本地变量,包括您的数组)被破坏,并且任何访问它们的尝试都会产生未定义的行为。
但是,如果您确实需要返回指向数组的指针,以便您存储的值可以在调用 function 中使用,那么您确实需要动态分配它,当您使用 calloc 动态分配 memory 时,生命周期从memory 被分配,直到它被释放。
请记住,静态分配的 memory 比动态分配的更快、更高效,所以如果你真的不需要它,不要花哨。
实现有条件地支持可变长度 arrays。
如果定义了宏名称__STDC_NO_VLA__
则 integer 常量 1,意在表明该实现不支持可变长度 arrays 或可变修改类型。
另一个问题是堆栈 memory 通常远小于用于动态 memory 分配的 memory。
可变长度数组的大小可以自动更改,然后控件重新到达数组的声明。
可变长度 arrays 具有自动存储持续时间和块范围。 所以它们在定义它们的块作用域中是活跃的。
可以使用 function 重新分配来调整动态分配的数组的大小,保留其元素的当前值,并且当动态分配的数组没有足够的空间时,您可以在程序中显式控制情况。
一般来说,只有真正安全地使用变长 arrays 是针对多维 arrays 的局部typedef
。 其他任何事情都是可疑的。 就像是:
void *buf = calloc(a*b, sizeof(int));
typedef int Int2d[a][b];
Int2D *array2d = buf;
(*array2d)[y][x] = 42;
所以使用calloc
版本。 仅当您有已知的小尺寸时,才直接使用 VLA。 是的,这有点矛盾。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.