考虑以下C代码:
#include <stdio.h>
#include<stdlib.h>
int main() {
int arrSize;
scanf("%d", &arrSize);
printf("%d\n",arrSize);
int *dynArr = (int *)malloc(sizeof(int)*arrSize);
int arr1[arrSize];
return 0;
}
在上面的代码中,arrSize是作为用户输入的数组的大小。 以下观察结果是否正确:
i) dynArr 是一个动态数组,在运行时从堆部分分配内存。可以使用 realloc 函数修改dynArr的大小。
ⅱ)。 arr1 也在运行时分配内存,但不是动态的,即它们的大小无法修改。内存是从堆栈或数据部分分配的。 (不确定分配内存的堆或堆栈/数据部分以及原因)。
答案 0 :(得分:5)
i)dynArr是一个动态数组,在运行时分配内存 从堆部分。可以使用realloc修改dynArr的大小 功能
是的,如果main
可以找到足够大的块。虽然从技术上讲,指针不是数组。它指向到数组的第一个元素。
ⅱ)。 arr1在运行时也分配了内存,但不是动态的 即它们的大小不能修改。内存从堆栈中分配 或数据部分。 (不确定从哪个部分堆或堆栈/数据 内存已分配,为什么)。
数组的大小是动态的,它的生命周期不是。它会在malloc
返回的那一刻自动回收。可变长度数组通常在调用堆栈上分配。是的,一旦你宣布它就不能改变它的大小。
如果您现在想知道何时使用一个而不是另一个,则需要考虑以下几点:
为调用堆栈保留的内存是有限的(远远超过堆)。如果你宣布一个巨大的VLA,很容易溢出。
从malloc
返回的内存及其亲属可以比分配它的堆栈帧更长。
通常,分配VLA比使用{{1}}分配内存要快。一个是堆栈帧指针的简单进展,而另一个是堆的内存分配器及其逻辑。
答案 1 :(得分:3)
dynArr
是一个动态数组,在运行时从堆部分分配内存。可以使用dynArr
函数修改realloc
的大小。
否,dynArr
是指针,使用malloc()
返回的指针进行初始化。记得,arrays are not pointers and vice-versa。在某些情况中,数组名称衰减为指向数组第一个元素的指针,但这并不能使两者相同。
dynArr
的大小是指针的大小,不是它指向的内存位置的大小。使用正确的单词,in可以表示为,指向的内存大小可以使用realloc()
进行更改。
arr1
在运行时也会分配内存,但不是动态的,即它们的大小无法修改。内存是从堆栈或数据部分分配的。 (不确定分配内存的堆或堆栈/数据部分以及原因)。
这称为variable length array。其他观点是正确的。
引用C11
,章节§6.7.6.2
如果size是一个不是整数常量表达式的表达式:如果它出现在a中 在函数原型范围内声明,它被视为被*替换;除此以外, 每次评估时,它的值应大于零。每个实例的大小 可变长度数组类型在其生命周期内不会改变。
答案 2 :(得分:1)
它从可用内存存储分配内存。现在,在C ...的情况下,内存中没有任何内容称为堆和堆栈。在C
的情况下,我们在逻辑上考虑这一点。(在C的实现中)]
我们唯一担心的是,即使声明的范围是否结束,我们是否需要您想要活着的东西。
对于堆来说就是这种情况..对于堆栈它不是。
int arr1[arrSize];
分配在存储此主函数局部变量的同一帧上。
您可以控制这些内存的确切大小和生命周期 位置。如果你没有释放它,你就会遇到内存泄漏问题 可能会导致您的应用程序崩溃,因为它在某些时候不能 分配更多的内存。 (
dynArr
)
堆是计算机内存中未管理的区域 自动为您服务,不受CPU的严密管理。它是 一个更自由浮动的内存区域(并且更大)。分配 堆上的内存,必须使用malloc()或calloc() 内置C函数。
一旦你在堆上分配了内存,你就可以了 一旦你负责使用free()来释放那个记忆 不再需要了。如果你没有这样做,你的程序就会有 所谓的内存泄漏。也就是说,堆上的内存仍然存在 被搁置(并且不会被其他进程使用)。
它是计算机内存的一个特殊区域,可以临时存储 每个函数创建的变量(包括main()函数)。 堆栈是&#34; LIFO&#34; (后进先出)数据结构,即 由CPU密切管理和优化。每次都有功能 声明一个新的变量,它是&#34;推的&#34;到堆栈上。 然后每一个 函数退出的时间,所有变量都被压入堆栈 该功能被释放(也就是说,它们被删除)。一旦 释放堆栈变量,该内存区域变为可用 其他堆栈变量。
答案 3 :(得分:0)
实际上,Google C ++样式指南中不允许使用可变长度数组。它具有自然的语法并且效率很高,但是,因为它们分配了数据依赖的堆栈空间量,它可以触发严重且神秘的内存覆盖错误:
有时“它在我的机器上运行良好,但在生产中神秘地死了”。