繁体   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