C语言 堆栈变量与堆变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5258724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Stack variables vs. Heap variables
提问by Hyman Harvin
Am I correct in thinking that:
我的想法是否正确:
char *buff[500];
... creates a stack variable, and:
... 创建一个堆栈变量,并且:
char *buff = (char *)malloc(500);
... creates a heap variable?
... 创建一个堆变量?
If that's correct, when and why would you use heap variables over stack variables and vice versa. I understand the stack is faster is there anything else.
如果这是正确的,那么何时以及为什么要在堆栈变量上使用堆变量,反之亦然。我知道堆栈更快还有其他什么。
One last question, is the main function a stack frame on the stack?
最后一个问题,主函数是栈上的栈帧吗?
回答by Arkaitz Jimenez
Yes, first one creates an array of char pointers in the stack, about 500*4 bytesand second one allocates 500 chars in the heap and points a stack char ptr to them.
是的,第一个在堆栈中创建一个字符指针数组,500*4 bytes第二个在堆中分配 500 个字符并将堆栈字符 ptr 指向它们。
Allocating in the stack is easy and fast, but stack is limited, heap is slower but much bigger. Apart from that, stack allocated values are "deleted" once you leave the scope, so it is very good for small local values like primitive variables.
在堆栈中分配既简单又快速,但堆栈是有限的,堆更慢但要大得多。除此之外,一旦离开范围,堆栈分配的值就会被“删除”,因此对于像原始变量这样的小局部值非常有用。
If you allocate too much in the stack you might run out of stack and die, mainas all the functions you execute has a stack frame in the stack and all the local variables to the function are stored there, so going too deep into function calling might get you into a stackoverflow as well.
如果您在堆栈中分配太多,您可能会用完堆栈并死掉,main因为您执行的所有函数在堆栈中都有一个堆栈帧,并且该函数的所有局部变量都存储在那里,因此对函数调用过于深入可能让您也进入 stackoverflow。
In general is a good rule of thumb to allocate anything that you use often and is bigger than a hundred bytes in the heap, and small variables and pointers in the stack.
一般来说,分配你经常使用的任何东西是一个很好的经验法则,在堆中大于一百个字节,在堆栈中分配小变量和指针。
回答by Bernd Elkemann
Seeing that you wrote
看到你写的
char *buff = (char *)malloc(500);
you probably meant
你可能是说
char buff[500]; instead of
char* buff[500];
in your first example (so you have a char-array, not an array of pointers to chars)
在你的第一个例子中(所以你有一个字符数组,而不是一个指向字符的指针数组)
Yes, "allocation" on the stack is faster because you just increase a pointer stored in the ESP register.
是的,堆栈上的“分配”速度更快,因为您只需增加存储在 ESP 寄存器中的指针。
You needheap-variables if you want:
如果需要,则需要堆变量:
1) more memory than fits in the stack (generally much earlier)
1) 比堆栈中容纳更多的内存(通常要早得多)
2) pass memory that was allocated by a called function to the calling function.
2) 将被调用函数分配的内存传递给调用函数。
回答by pmg
Your buffs are not equivalent.
你的buffs 是不等价的。
The first one (char *buff[500]) is an array of 500 pointers; the 2nd one (char *buff = (char *)malloc(500)) is a pointer.
第一个 ( char *buff[500]) 是一个包含 500 个指针的数组;第二个 ( char *buff = (char *)malloc(500)) 是一个指针。
The pointer (on the stack) points to 500 bytes of memory (if the malloc call succeeded) on the heap.
The array of pointers is on the stack. Its pointers are not initialized.
指针(在堆栈上)指向堆上的500 字节内存(如果 malloc 调用成功)。
指针数组在堆栈上。它的指针没有被初始化。
回答by Lightness Races in Orbit
Unless using C99, using the stack the size of your array must be known at compile-time. That means you cannot do:
除非使用 C99,否则在编译时必须知道使用堆栈的数组大小。这意味着你不能这样做:
int size = 3; // somewhere, possibly from user input
char *buff[size];
But using "the heap" (dynamic allocation), you can provide any dimensions you like. That's because the memory allocation is performed at run-time, rather than hardcoded into the executable.
但是使用“堆”(动态分配),您可以提供您喜欢的任何维度。这是因为内存分配是在运行时执行的,而不是硬编码到可执行文件中。
回答by krtek
Heap variables can be created dynamically, ie you can ask a size to your user and malloc a new variable with this size.
堆变量可以动态创建,即您可以向您的用户询问一个大小并使用这个大小分配一个新变量。
The size of a stack variable must be known at compile time.
在编译时必须知道堆栈变量的大小。
Like you said, stack variable are faster allocated and accessed. So i'll recommend using them every time you know the size at compile time. Otherwise you don't have the choice, you must use malloc()
就像你说的,堆栈变量的分配和访问速度更快。所以我会建议你每次在编译时知道大小时使用它们。否则你没有选择,你必须使用malloc()
回答by Antti Haapala
The C standard contains neitherthe words heapnor stack. What we have here instead are two storage durations (of 4 in total): automaticand allocated:
C 标准既不包含单词heap也不包含stack。我们这里有两个存储持续时间(总共 4 个):自动和分配:
char buff[500]; // note the missing * to match the malloc examplewithin a functiondeclares the object
buffas an array ofcharand having automatic storage duration. The object will cease to be when the block where the object was declared, is exited.char *buff = malloc(500); // no cast necessary; this is Cwill declare
buffas a pointer tochar.mallocwill reserve 500 continuous bytes and return a pointer to it. The returned 500-byte object will exist until it is explicitlyfreed with a call tofree. The object is said to have allocated storage duration.
char buff[500]; // note the missing * to match the malloc example在函数中将对象声明
buff为 的数组char并具有自动存储持续时间。当声明对象的块退出时,对象将不再存在。char *buff = malloc(500); // no cast necessary; this is C将声明
buff为指向char.malloc将保留 500 个连续字节并返回指向它的指针。返回的 500 字节对象将一直存在,直到它被显式free调用 d为止free。据说该对象已分配存储期。
That's all the C standard says. It doesn't specify that the char buff[500]needs to be allocated from a "stack", or that there needs to be a stack. It doesn't specify that the mallocneeds to use some "heap". On the contrary, a compiler might internally implement the char buff[500]like
这就是 C 标准所说的全部内容。它没有指定char buff[500]需要从“堆栈”分配,或者需要有一个堆栈。它没有指定malloc需要使用一些“堆”。相反,编译器可能在内部实现char buff[500]类似
{
char *buff = malloc(500);
free(buff);
}
Or it can deduce that the allocated memory is not used, or that it is only used once, and use a stack-based allocation instead of actually calling malloc.
或者它可以推断分配的内存没有使用,或者它只使用了一次,并使用基于堆栈的分配而不是实际调用malloc.
In practice, most current compilers and environments willuse a memory layout called stackfor automatic variables, and the objects with allocated storage duration are said to come from "heap" which is a metaphor for the unorganized mess that it is compared to the orderly stack, but it is not something that has to be so.
在实践中,大多数当前的编译器和环境将使用称为堆栈的内存布局来存储自动变量,并且据说具有分配存储期的对象来自“堆”,这是将其与有序堆栈进行比较的无组织混乱的隐喻,但并非必须如此。
回答by Jon
This is indeed a variable allocated on the stack:
这确实是一个分配在堆栈上的变量:
char buff[500]; // You had a typo here?
and this is on the heap:
这是在堆上:
char *buff = (char *)malloc(500);
Why would you use one vs the other?
你为什么要使用一个和另一个?
- In
char *buff[500], the500needs to be a compile-time constant. You can't use it if500is computed at runtime. - On the other hand, stack allocations are instantaneous while heap allocations take time (thus they incur a runtime performance cost).
- Space on the stack is limited by the thread's stack size (typically 1MB before you get a stack overflow), while there's much more available on the heap.
- If you allocate an array on the stack big enough to take up more than 2 pages of virtual memory as managed by the OS, and access the end of the array before doing anything else, there's the possibility of getting a protection fault (this depends on the OS)
- 在 中
char *buff[500],500需要是编译时常量。如果500在运行时计算,则不能使用它。 - 另一方面,堆栈分配是即时的,而堆分配需要时间(因此它们会产生运行时性能成本)。
- 堆栈上的空间受线程堆栈大小的限制(在堆栈溢出之前通常为 1MB),而堆上还有更多可用空间。
- 如果您在堆栈上分配的数组足够大以占用 OS 管理的 2 页以上的虚拟内存,并在执行任何其他操作之前访问数组的末尾,则可能会出现保护错误(这取决于操作系统)
Finally: every function called has a frame on the stack. The mainfunction is no different. It isn't even any more special than the other functions in your program, since when your program starts running the first code that runs is inside the C runtime environment. After the runtime is ready to begin execution of your own code, it calls mainjust as you would call any other function.
最后:每个调用的函数在堆栈上都有一个框架。该main功能并没有什么不同。它甚至并不比程序中的其他函数更特殊,因为当您的程序开始运行时,运行的第一个代码在the C runtime environment. 在运行时准备好开始执行您自己的代码后,它main会像调用任何其他函数一样调用。
回答by Novikov
Those two aren't equivalent. The first is an array of size 500 (on the stack) with pointers to characters. The second is a pointer to a memory chunk of 500 which can be used with the indexing operator.
这两个不是等价的。第一个是大小为 500(在堆栈上)的数组,带有指向字符的指针。第二个是指向可与索引运算符一起使用的 500 内存块的指针。
char buff[500];
char *buff = (char *)malloc(sizeof(char)*500);
Stack variables should be preferred because they require no deallocation. Heap variables allow passing of data between scopes as well as dynamic allocation.
堆栈变量应该是首选,因为它们不需要重新分配。堆变量允许在作用域之间传递数据以及动态分配。

