[英]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.