c - 在 c 中每个函数都有自己的堆栈吗?

标签 c gcc stack-overflow

我最近了解了堆栈,因此我正在尝试查看堆栈大小以及溢出时会发生什么。我发现在 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/

    相关文章:

    c - 使用套接字将数据包发送到另一个子网/网络

    c - 我在功能上做错了什么?

    gcc - 如何使用 g++ 覆盖像 __libc_start_main 这样的入口点

    c++ - 快速排序导致计算器溢出?

    go - LeetCode排列-代码日志

    c - 被动运动检测

    C(Linux 上的 gcc): How do i convert a hex string "0xfffffff" to an integer?

    c++ - 如何让 cmake 使用 "-pthread"而不是 -lpthread”?

    c++ - GCC 的调试堆/STL 调试等价物?

    spring-boot - @SpringBootTest 注解导致 StackOverflowError