我对此很好奇:
两者之间的区别是什么:
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
和:
char Buffer[MAX_BUF];
-
案例 1:在
char Buffer[MAX_BUF];
Buffer
是一个大小MAX_BUF
数组。分配技术称为 VLA。 -
案例 2:在
const int MAX_BUF = 1000; char* Buffer = malloc(MAX_BUF);
Buffer
是一个指针,它分配了一个大小为MAX_BUF
的内存,该内存
1000
。而且,数组与指针不同,C-FAQ 有一个非常好的集合详细说明了原因。
在可用性和行为方面的主要区别是:
- (1( 在堆栈上,通常是 Note,而 (2( 总是在堆上。 (
- 1(分配后具有固定大小,(2(可以调整大小。
- (1( 在调用封闭函数并具有块范围 OTOH 时分配,(2( 在运行时动态分配内存,返回的内存具有从分配到释放的生命周期。 (
- 1(分配的内存不需要由程序员管理,而在(2(中,所有
malloc()
d内存都应该free()
d。
注:维基
例如,GNU C 编译器为堆栈上的 VLA 分配内存。
除了其他人所说的之外,我还会在内存管理方面添加一些信息。
1(主要区别在这里:
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
您需要手动管理分配的内存,例如,使用完后Buffer
释放内存。忘记free
它(或释放它两次(可能会导致麻烦。
2(对于第二种情况:
char Buffer[MAX_BUF];
您不需要释放任何东西。它会自动被销毁。因此,您可以避免处理内存的任务 - 这很好。您应该尝试始终评估您需要哪种方法。
几点。
- 由于第二个是在堆栈上分配的,因此当需要创建大型数组时,也会采用第一种方法 - 因为堆上通常有更多的内存可用。
- 此外,如果您使用第二种方法创建数组,例如在方法中,对象的生命周期将是该方法 - 您将无法在该方法之外使用该数组。而动态分配则不是这样。
char* Buffer = malloc(MAX_BUF);
创建一个char
指针Buffer
,通过malloc
动态分配MAX_BUF
字节的内存,并使Buffer
指向分配空间的开头。此内存在堆上分配。
char Buffer[MAX_BUF];
创建一个大小为 MAX_BUF
的数组Buffer
,最多可容纳 MAX_BUF
个字符。请注意,您正在创建一个可变长度数组(C99 中引入的功能(,因为MAX_BUF
是一个变量。可以在堆栈上创建此数组。
最显着的区别是范围。VLA 数组仅在声明它的范围内有效,而动态数组将在程序中的任何位置可用,直到您调用 free()
。
实际上,VLA 可能比动态内存快,以防编译器对 VLA 使用堆栈分配。但是,分配VLA的C标准没有指定。
(理论上,编译器可以在堆上分配VLA,但编译器也将负责清理。我认为不存在任何这样的解决方案。我使用过的每个编译器总是在堆栈上声明 VLA。
这意味着 VLA 不适合保存大量数据:您可能会面临堆栈溢出的风险。但是,当您使用动态内存时,这不是问题。
VLA 不具有与动态数组相同的可移植性,因为非常旧的编译器不支持 VLA。从理论上讲,新的 C11 编译器也不必支持 VLA,尽管在这一点上,我知道没有编译器愚蠢到放弃这种支持。
比较/总结:
- 当本地数据量较少时,应使用 VLA,因为它们具有快速分配时间和自动清理功能。
- 当有大量数据时,应使用动态数组,以防止堆栈溢出。
- 当数据需要在函数执行后持久化并在程序的其他位置可用时,应使用动态数组。
- 当您有特殊和/或不合理的可移植性要求时,应使用动态数组。