堆栈变量与堆变量

时间:2011-03-10 11:00:33

标签: c

我认为这是正确的:

char *buff[500];

...创建一个堆栈变量,并且:

char *buff = (char *)malloc(500);

...创建堆变量?

如果这是正确的,何时以及为什么要将堆变量用于堆栈变量,反之亦然。我知道堆栈速度更快还有别的。

最后一个问题,堆栈框架的主要功能是什么?

8 个答案:

答案 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,则无法使用它。
  • 另一方面,堆分配是即时的,而堆分配需要时间(因此它们会产生运行时性能成本)。
  • 堆栈上的空间受到线程堆栈大小的限制(在堆栈溢出之前通常为1MB),而堆上的可用空间更多。
  • 如果您在堆栈上分配的数组大到足以占用操作系统管理的超过2页的虚拟内存,并在执行任何其他操作之前访问数组的末尾,则可能会出现保护错误(这取决于操作系统)

最后:调用的每个函数在堆栈上都有一个框架。 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);

堆栈变量应该是首选,因为它们不需要重新分配。堆变量允许在范围之间传递数据以及动态分配。