我最近了解了堆栈,因此我正在尝试查看堆栈大小以及溢出时会发生什么。我发现在 Unix 上默认堆栈大小为 8 MiB,这支持我的发现,因为我无法在 main
中声明大小大于或等于 8 MiB 的字符串。功能。但是,当我在 main()
中声明一个变量时它会影响其他功能。例如:
#include <stdio.h>
void foo(void)
{
long int size = 1024*1024*2;
char str[size];
str[size - 1] = 'a';
printf("%c\n", str[size - 1]);
}
int main(int argc, char** argv)
{
long int size = 1024*1024*6;
char str[size];
str[size - 1] = 'a';
printf("%c\n", str[size - 1]);
foo();
return 0;
}
此代码导致段错误,但如果我在
main()
中将字符串大小设为 5 MiB那么就没有段错误。这是否意味着我的 C 程序不能为局部变量(所有函数)分配超过 8 MiB 的 RAM?如果是这样,堆栈的重点是什么?
最佳答案
不,每个函数都没有自己独立的堆栈空间。您的程序中只有一个堆栈,并且有一个 有限数量的堆栈空间 可供您使用。
堆栈的工作原理
This LIFO behavior is exactly what a function does when returning to the function that called it.
堆栈中的流动
调用堆栈外的地址(这个弹出的元素也称为
堆栈帧 ) 并将控制权转移到该地址。
另一个返回地址到 的顶部相同的调用堆栈 , 和
等等,有资料堆叠和卸载 作为
程序规定。
以上所有过程都发生在同一个堆栈内存中。每个函数在堆栈中都有自己的空间,但每个函数都在同一个堆栈中分配空间。这称为 全局调用栈你的程序。
它用于存储函数内部使用的局部变量。
然而,动态分配空间存储在堆上。 堆用于存储动态变量 .它是进程内存的一个区域。
malloc()
, calloc()
, resize()
所有这些内置函数通常用于存储动态变量。至于堆栈溢出 问题,调用堆栈大小是有限的。只能使用一定数量的内存。如果发生多次函数调用,堆栈空间最终会耗尽,这会给你一个 堆栈溢出错误 这很可能会导致您的 程序崩溃 .
如果你的函数中有很多变量,或者你的程序中有一些需要大量空间的变量,那么堆栈空间最终会耗尽并导致堆栈溢出 .例如。在大多数情况下,以下内容可能会导致堆栈溢出并导致程序崩溃:
int main() {
int A[100000][100000];
}
希望这可以消除您的疑虑!注意 :
在多线程环境中,每个线程得到它的自己的调用栈空间分开而不是具有相同的 全局调用栈 .因此,在多线程环境中,您的问题的答案将是 是 .
关于c - 在 c 中每个函数都有自己的堆栈吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62107481/