Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 堆栈变量与堆变量_C - Fatal编程技术网

C 堆栈变量与堆变量

C 堆栈变量与堆变量,c,C,我认为: char *buff[500]; 。。。创建堆栈变量,并执行以下操作: char *buff = (char *)malloc(500); 。。。创建堆变量 如果这是正确的,那么何时以及为什么要在堆栈变量上使用堆变量,反之亦然。我知道堆叠速度更快,还有其他的吗 最后一个问题,主要功能是堆栈上的堆栈帧吗?是的,第一个在堆栈中创建一个字符指针数组,大约为500*4字节,第二个在堆中分配500个字符,并将堆栈字符ptr指向它们 在堆栈中进行分配既简单又快速,但堆栈有限,堆速度较慢,但要大

我认为:

char *buff[500];
。。。创建堆栈变量,并执行以下操作:

char *buff = (char *)malloc(500);
。。。创建堆变量

如果这是正确的,那么何时以及为什么要在堆栈变量上使用堆变量,反之亦然。我知道堆叠速度更快,还有其他的吗


最后一个问题,主要功能是堆栈上的堆栈帧吗?

是的,第一个在堆栈中创建一个字符指针数组,大约为
500*4字节
,第二个在堆中分配500个字符,并将堆栈字符ptr指向它们

在堆栈中进行分配既简单又快速,但堆栈有限,堆速度较慢,但要大得多。除此之外,一旦您离开范围,堆栈分配的值就会被“删除”,因此对于像原语变量这样的小型局部值来说这是非常好的

如果在堆栈中分配太多,可能会耗尽堆栈并导致死亡,
main
,因为您执行的所有函数在堆栈中都有一个堆栈帧,并且函数的所有局部变量都存储在堆栈帧中,因此过于深入函数调用也可能导致堆栈溢出


一般来说,分配您经常使用的、堆中大于100字节的任何内容以及堆栈中的小变量和指针是一个很好的经验法则。

堆变量可以动态创建,也就是说,您可以向用户请求一个大小,并使用此大小malloc一个新变量

堆栈变量的大小必须在编译时已知


正如您所说,堆栈变量的分配和访问速度更快。因此,我建议您在编译时每次知道大小时都使用它们。否则您没有选择权,必须使用
malloc()

除非使用C99,否则使用堆栈时必须在编译时知道数组的大小。这意味着你不能做:

int size = 3; // somewhere, possibly from user input
char *buff[size];
但是使用“heap”(动态分配),您可以提供任何您喜欢的维度。这是因为内存分配是在运行时执行的,而不是硬编码到可执行文件中

char *buff = (char *)malloc(500);
你可能是说

char buff[500];    instead of 
char* buff[500];
在第一个示例中(因此您有一个char数组,而不是指向char的指针数组)

是的,堆栈上的“分配”更快,因为您只需增加存储在ESP寄存器中的指针

如果需要,您需要堆变量:

1) 内存超过堆栈中的容量(通常更早)


2) 将被调用函数分配的内存传递给调用函数。

这确实是堆栈上分配的变量:

char buff[500]; // You had a typo here?
这是堆上的:

char *buff = (char *)malloc(500);
你为什么要用一个来对抗另一个

  • char*buff[500]
    中,
    500
    需要是编译时常量。如果在运行时计算了
    500
    ,则不能使用它
  • 另一方面,堆栈分配是即时的,而堆分配需要时间(因此它们会导致运行时性能成本)
  • 堆栈上的空间受到线程堆栈大小的限制(通常在堆栈溢出之前为1MB),而堆上的可用空间要多得多
  • 如果在堆栈上分配一个数组,该数组的大小足以占用操作系统管理的2页以上的虚拟内存,并且在执行任何其他操作之前访问该数组的末尾,则可能会出现保护故障(这取决于操作系统)

最后:调用的每个函数在堆栈上都有一个框架。
main
功能也不例外。它甚至不比程序中的其他函数更特殊,因为当程序开始运行时,运行的第一个代码就在C运行时环境中。运行时准备好开始执行您自己的代码后,它将调用
main
,就像您调用任何其他函数一样。

这两个函数并不等效。第一个是一个大小为500的数组(在堆栈上),带有指向字符的指针。第二个是指向500的内存块的指针,该内存块可与索引运算符一起使用

char buff[500];

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

应首选堆栈变量,因为它们不需要释放。堆变量允许在作用域之间传递数据以及动态分配

您的
buff
s不是等效的

第一个(
char*buff[500]
)是500个指针的数组;第二个(
char*buff=(char*)malloc(500)
)是指针

指针(堆栈上的)指向堆上的500字节内存(如果malloc调用成功)。
指针数组位于堆栈上。它的指针未初始化。

C标准既不包含单词heap,也不包含单词stack。我们这里有两个存储持续时间(共4个):自动和分配:

  • 在函数中,将对象
    buff
    声明为
    char
    的数组,并具有。当声明对象的块退出时,该对象将停止

  • buff
    声明为指向
    char
    的指针
    malloc
    将保留500个连续字节并返回指向该字节的指针。返回的500字节对象将一直存在,直到调用
    free
    显式地
    free
    为止。据说这个物体有两个


这就是C标准的全部内容。它没有指定需要从“堆栈”分配
字符buff[500]
,或者需要有一个堆栈。它没有指定
malloc
需要使用一些“堆”。相反,编译器可能会在内部实现
charbuff[500]
之类的

{
    char *buff = malloc(500);
    free(buff);
}
或者它可以推断分配的内存没有使用,或者只使用了一次,并使用基于堆栈的分配,而不是实际调用
malloc

实际上,大多数当前的编译器和环境都会使用一种称为堆栈的内存布局来处理自动变量,并且具有分配的存储持续时间的对象被称为来自“heap”w
char *buff = malloc(500);  // no cast necessary; this is C
{
    char *buff = malloc(500);
    free(buff);
}