我们了解到C和动态变量中存在动态内存:
#include <stdio.h>
int a = 17;
int main(void)
{
int b = 18; //automatic stack memory
int * c;
c = malloc( sizeof( int ) ); //dynamic heap memory
*c = 19;
printf("a = %d at address %x\n", a, &a);
printf("b = %d at address %x\n", b, &b);
printf("c = %d at address %x\n", *c, c);
free(c);
system("PAUSE");
return 0;
}
我如何知道要使用哪种类型的内存?什么时候该怎么做?
答案 0 :(得分:23)
在以下情况下使用动态:
当你需要大量内存时。典型的堆栈大小为1 MB,因此大于50-100KB的任何内容都应该更好地动态分配,否则您将面临崩溃的风险。有些平台的限制甚至更低。
当函数返回后内存必须存在时。当函数结束时,堆栈内存被破坏,动态内存在你想要时被释放。
当您构建大小未知(即可能变大)的结构(如数组或图形)时,动态更改或难以预先计算。动态分配允许您的代码在任何时刻自然地并且仅在您需要时自然地请求内存。在for
循环中不可能重复请求越来越多的堆栈空间。
否则首选堆栈分配。它更快,不会泄漏。
答案 1 :(得分:4)
只有在运行时才预先知道分配大小时,才使用动态内存。
例如,您要求用户输入名称(最多10个名称)并将其存储在字符串数组中。由于您不知道用户将提供多少名称(仅在运行时),因此只有在知道要分配多少数据后才需要分配数组,因此您将使用动态分配。
你当然可以使用固定大小的数组10,但是对于更大的数量,这将是浪费
答案 2 :(得分:2)
如果您不知道完全您的程序在编译时需要分配多少内存,请使用动态内存分配。
例如, int a[n]
会将您的数组大小限制为n。此外,无论您是否使用它,它都会分配n x 4字节的内存。这是在堆栈上分配的,变量n 必须在编译时才知道。
int *a = (int *)malloc(n * sizeof (int))
在运行时,在堆上分配,n
只需要在运行时知道,而不一定在编译时。
这也确保您可以根据实际需要分配尽可能多的内存。但是,由于你在运行时分配了它,因此必须使用free
进行清理。
答案 3 :(得分:2)
在以下情况下应使用动态内存:
请注意,c99标准在C中引入了 可变长度数组(VLA) ,因此您不需要使用动态内存分配,因为您之前不知道数组维度(除非上面提到的#2
是这种情况)
最好尽可能避免动态内存分配,因为这意味着 明确管理内存 而不是 自动机制 由语言提供。明确的内存管理意味着您容易犯更多错误,这可能会导致灾难性的后果。
已经说过,动态内存分配总是无法避免,必须在必要时使用(上面提到的两种情况)。
答案 4 :(得分:2)
如果你可以在没有动态分配的情况下编程,请不要使用它!
但是有一天你会被阻止,解锁你的唯一方法就是使用动态分配,然后就可以使用了它
答案 5 :(得分:1)
Als提出了一个有趣的观点,如果你的对象需要超出创建它的范围,你应该从堆中分配内存。在上面的代码中,您根本不需要从堆中分配内存。你可以像这样重写它:
#include <stdio.h>
int a = 17;
int main(void)
{
int b = 18; //automatic stack memory
int c[1]; // allocating stack memory. sizeof(int) * 1
c[0] = 19;
printf("a = %d at address %x\n", a, &a);
printf("b = %d at address %x\n", b, &b);
printf("c = %d at address %x\n", c[0], c);
system("PAUSE");
return 0;
}
实际上,作为C99标准(Variable-length array)的一部分,您可以使用[]
运算符为堆栈上的数组分配动态空间,就像通常创建数组一样。您甚至不需要在编译时知道数组的大小。编译器将根据请求的分配空间调整esp寄存器(对于x86
机器),你很高兴。