为什么在我们可以用c编写代码时使用malloc函数:
int size;
printf("please the size of the array\n");
scanf("%d",&size);
int arr[size];
这消除了将垃圾值分配给数组大小的可能性,并且还在运行时获取数组的大小......
那么为什么在这样做的时候可以使用动态内存分配呢?
答案 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];
内存不足。 int arr[size];
可能超出资源而未被发现。 @Weather Vane代码可以使用NULL
进行*alloc()
检查来检测失败。
int *arr = malloc(sizeof *arr * size);
if (arr == NULL && size > 0) Handle_OutOfMemory();
int arr[size];
不允许数组大小为0. malloc(sizeof *arr * 0);
不是主要问题。它可能会返回NULL
或成功指针,但这很容易处理。
注意:对于数组大小,类型size_t
最好是无符号整数类型 - 既不太窄也不太宽。如果int arr[size];
,则size < 0
为UB。这也是malloc(sizeof *arr * size)
的问题。对于可变长度数组(VLA)和size
,不合格的*alloc()
不是一个好主意。
自C99以来所需的VLA仅在兼容的C11编译器中可选。