我认为这是正确的:
char *buff[500];
...创建一个堆栈变量,并且:
char *buff = (char *)malloc(500);
...创建堆变量?
如果这是正确的,何时以及为什么要将堆变量用于堆栈变量,反之亦然。我知道堆栈速度更快还有别的。
最后一个问题,堆栈框架的主要功能是什么?
答案 0 :(得分:56)
是的,第一个在堆栈中创建一个char指针数组,大约500*4 bytes
,第二个在堆中分配500个字符,并将堆栈char ptr指向它们。
在堆栈中分配既简单又快速,但堆栈有限,堆慢但更大。除此之外,一旦离开范围,堆栈分配的值就会被“删除”,因此对于像原始变量这样的小本地值非常有用。
如果在堆栈中分配太多,则可能会耗尽堆栈并死掉main
,因为您执行的所有函数在堆栈中都有一个堆栈帧,并且函数的所有局部变量都存储在那里,所以进入函数调用太深可能会让你进入stackoverflow。
一般来说,分配你经常使用的任何东西并且在堆中大于一百个字节,以及堆栈中的小变量和指针是一个很好的经验法则。
答案 1 :(得分:9)
看到你写了
char *buff = (char *)malloc(500);
你可能意味着
char buff[500]; instead of
char* buff[500];
在你的第一个例子中(所以你有一个char数组,而不是一个指向字符的指针数组)
是的,堆栈上的“分配”更快,因为你只需增加存储在ESP寄存器中的指针。
如果您愿意,需要堆变量:
1)内存多于堆栈中的内存(通常更早)
2)将被调用函数分配的内存传递给调用函数。
答案 2 :(得分:9)
您的buff
不等同。
第一个(char *buff[500]
)是一个包含500个指针的数组;第二个(char *buff = (char *)malloc(500)
)是指针。
指针(堆栈上的 )指向堆上500字节的内存(如果malloc调用成功)。 指针数组在堆栈上。它的指针没有初始化。
答案 3 :(得分:4)
除非使用C99,否则必须在编译时知道数组的大小。这意味着你不能这样做:
int size = 3; // somewhere, possibly from user input
char *buff[size];
但是使用“堆”(动态分配),您可以提供您喜欢的任何尺寸。这是因为内存分配是在运行时执行的,而不是硬编码到可执行文件中。
答案 4 :(得分:1)
堆变量可以动态创建,即您可以向用户询问大小,并使用此大小malloc一个新变量。
必须在编译时知道堆栈变量的大小。
就像你说的那样,堆栈变量的分配和访问速度更快。因此,我建议每次在编译时知道大小时使用它们。否则您无法选择,必须使用malloc()
答案 5 :(得分:1)
这确实是在堆栈上分配的变量:
char buff[500]; // You had a typo here?
这是在堆上:
char *buff = (char *)malloc(500);
为什么你会使用一个与另一个?
char *buff[500]
中,500
需要是编译时常量。如果在运行时计算500
,则无法使用它。最后:调用的每个函数在堆栈上都有一个框架。 main
功能也不例外。它甚至不比程序中的其他函数更特殊,因为当程序开始运行时,第一个运行的代码在the C runtime environment
内。在运行时准备开始执行您自己的代码之后,它就像调用任何其他函数一样调用main
。
答案 6 :(得分:1)
C标准包含 堆和堆栈两个。我们这里有两个存储持续时间(总共4个):自动和已分配:
char buff[500]; // note the missing * to match the malloc example
函数中的 将对象buff
声明为char
并具有automatic storage duration的数组。当退出声明对象的块时,该对象将停止。
char *buff = malloc(500); // no cast necessary; this is C
会将buff
声明为指向char
的指针。 malloc
将保留500个连续字节并返回指向它的指针。返回的500字节对象将一直存在,直到明确free
d并调用free
。该对象据说有allocated storage duration。
所有C标准都说。它没有指定char buff[500]
需要从"堆栈"中分配,或者需要堆栈。它没有指定malloc
需要使用一些" heap"。相反,编译器可能在内部实现char buff[500]
之类的
{
char *buff = malloc(500);
free(buff);
}
或者它可以推断出未使用分配的内存,或者只使用一次,并使用基于堆栈的分配而不是实际调用malloc
。
实际上,大多数当前编译器和环境将使用名为 stack 的内存布局作为自动变量,并且具有分配存储持续时间的对象据说来自&# 34;堆"这是一个无组织混乱的比喻,它与有序堆栈相比,但它不是必须如此。
答案 7 :(得分:0)
这两个不等同。第一个是大小为500的数组(在堆栈上),带有指向字符的指针。第二个是指向500的内存块的指针,它可以与索引操作符一起使用。
char buff[500];
char *buff = (char *)malloc(sizeof(char)*500);
堆栈变量应该是首选,因为它们不需要重新分配。堆变量允许在范围之间传递数据以及动态分配。