簡體   English   中英

C 中的動態 memory 分配用於可變長度 arrays

[英]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 在內的自動存儲持續時間對象(通過大多數現代實現)分配在堆棧上。 如果將較大的對象分配在堆棧上(三個最重要的),則會出現一些問題:

  1. 除非您的程序在堆棧溢出時失敗,否則沒有分配控制
  2. 堆棧通常比堆小得多。 所以數組的大小是有限的
  3. 數組的生命周期僅限於封閉塊的生命周期。 您不能在 function 返回上返回對此數組的引用。

巨大的區別在於,在第一個示例中,該數組僅在包含 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM