为什么在使用arr [size]声明数组时,在c中使用malloc函数,从用户那里获取大小的输入?

时间:2017-03-21 19:20:31

标签: c malloc

为什么在我们可以用c编写代码时使用malloc函数:

int size;
printf("please the size of the array\n");
scanf("%d",&size);
int arr[size];

这消除了将垃圾值分配给数组大小的可能性,并且还在运行时获取数组的大小......

那么为什么在这样做的时候可以使用动态内存分配呢?

4 个答案:

答案 0 :(得分:1)

这种表示法

int arr[size];

表示VLA - 可变长度数组。

它们实现的标准方式是它们在堆栈上分配。 这有什么问题? 堆栈通常比较小 - 在我的linux机器上它只有8MB。 因此,如果您尝试运行以下代码

#include <stdio.h>

const int MAX_BUF=10000000;

int main()
{
    char buf[MAX_BUF];
    int idx;
    for( idx = 0 ; idx < MAX_BUF ; idx++ )
      buf[idx]=10;
}

最终会出现seg错误。

TL; DR版

PRO: VLA适用于小额分配。离开范围时,你不必担心释放记忆。

反对: 它们对大型分配不安全。你不能告诉分配什么是安全的大小(比如递归)。

答案 1 :(得分:1)

除了VLA在尺寸太大时可能遇到问题这一事实外,还有更重要的事情:范围。

在遇到声明时分配VLA,在保留范围({ ... })时释放VLA。这具有优势(两个操作都不需要函数调用)和缺点(您无法从函数返回它或分配多个对象)。

malloc动态分配,因此内存块在从您碰巧进入的函数返回后仍然存在,您可以多次分配malloc(例如在for循环中)和您确定何时解除分配(通过调用free)。

答案 2 :(得分:0)

你所写的内容现在确实是一种可能性,但如果你用g ++这样做,就会发出警告(这通常是一件坏事)。

其他的是你的arr [size]存储在堆栈中,而malloc在堆中存储数据会给你更多的空间。

这可能与主要问题有关,也就是说,您实际上可以使用realloc或free以及另一个malloc来更改malloc&#d; d阵列的大小。你的阵列可以在整个住宿期间使用,你甚至无法在某些时候释放它以节省空间。

答案 3 :(得分:0)

为什么使用以下内容:

int size;
printf("please the size of the array\n");
scanf("%d",&size);
int arr[size];
  1. 内存不足。 int arr[size];可能超出资源而未被发现。 @Weather Vane代码可以使用NULL进行*alloc()检查来检测失败。

    int *arr = malloc(sizeof *arr * size);
    if (arr == NULL && size > 0) Handle_OutOfMemory();
    
  2. int arr[size];不允许数组大小为0. malloc(sizeof *arr * 0);不是主要问题。它可能会返回NULL或成功指针,但这很容易处理。

  3. 注意:对于数组大小,类型size_t最好是无符号整数类型 - 既不太窄也不太宽。如果int arr[size];,则size < 0为UB。这也是malloc(sizeof *arr * size)的问题。对于可变长度数组(VLA)和size,不合格的*alloc()不是一个好主意。

  4. 自C99以来所需的VLA仅在兼容的C11编译器中可选。