堆栈内存是否有限制?

Vik*_*kas 9 c heap stack operating-system memory-management

我正在经历其中一个主题.程序崩溃是因为它在函数内部声明了一个10 ^ 6的数组.

给出的原因是堆栈上的内存分配失败导致崩溃.

当全局声明相同的数组时,它运行良好.(堆上的内存保存了它).

现在,让我们假设,堆栈向下增长并向上堆积.

我们有:

- -堆 - -

-------------------

- -堆 - -

现在,我相信如果堆栈上的分配失败,它也必须在堆上失败.

所以我的问题是:堆栈大小有限制吗?(超过限制导致程序崩溃).或者我错过了什么?

Fox*_*ire 6

是的,堆栈总是有限的.在多种语言/编译器中,您可以设置所需的大小.

通常默认值(如果没有手动设置)对于当前语言大约是1MB,这是足够的,除非你做一些通常不推荐的事情(比如在堆栈上分配大数组)


And*_*nck 5

这完全取决于您使用的语言和编译器.但是使用例如C或C++编译的程序在程序启动时分配固定大小的堆栈.堆栈的大小通常可以在编译时指定(在我的特定编译器上它默认为1 MB).


lve*_*lla 5

与迄今为止的所有答案相反,在带有 GCC 的 Linux 上(我猜这对于所有现代 POSIX 操作系统都是如此),最大堆栈大小是操作系统强制执行的安全限制,可以轻松解除。

我编写了一个小程序,它递归调用一个函数,直到在堆栈上分配至少 10 GB 的空间,等待终端上的输入,然后安全地从所有递归调用返回到main.

#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>

void grow(unsigned cur_size)
{
    if(cur_size * sizeof(int) < 10ul*1024ul*1024ul*1024ul) {
        unsigned v[1000];
        v[0] = cur_size;
        for(unsigned i = 1; i < 1000; ++i) {
            v[i] = v[i-1] + 1;
        }

        grow(cur_size + 1000);

        for(unsigned i = 0; i < 1000; ++i) {
            if(v[i] != cur_size + i)
                puts("Error!");
        }
    } else {
        putchar('#');
        getchar();
    }
}

int main()
{
    struct rlimit l;
    l.rlim_max = RLIM_INFINITY;
    l.rlim_cur = RLIM_INFINITY;
    setrlimit(RLIMIT_STACK, &l);

    grow(0);
    putchar('#');
    getchar();
}
Run Code Online (Sandbox Code Playgroud)