堆栈内存有限制吗?

发布于 2024-08-31 08:24:34 字数 327 浏览 10 评论 0原文

我正在浏览其中一个线程。 程序崩溃是因为 它在函数内部本地声明了一个 10^6 的数组。

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

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

现在让我们假设, 栈向下增长,堆向上增长。

我们有:

---STACK---

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

---HEAP----

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

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

I was going through one of the threads.
A program crashed because
it had declared an array of 10^6 locally inside a function.

Reason being given was memory allocation failure on stack leads to crash.

when same array was declared globally, it worked well.(memory on heap saved it).

Now for the moment, let us suppose,
stack grows downward and heap upwards.

We have:

---STACK---

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

---HEAP----

Now , I believe that if there is failure in allocation on stack,
it must fail on heap too.

So my question is: is there any limit on stack size?
(crossing the limit caused the program to crash).
Or am I missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

源来凯始玺欢你 2024-09-07 08:24:34

是的,堆栈始终是有限的。在多种语言/编译器中,您可以设置请求的大小。

通常默认值(如果没有手动设置)约为当前语言的 1MB,这已经足够了,除非您执行通常不推荐的操作(例如在堆栈上分配巨大的数组)

Yes, stack is always limited. In several languages/compilers you can set the requested size.

Usually default values (if not set manually) are about 1MB for current languages, which is enough unless you do something that usually isn't recommended (like you allocating huge arrays on the stack)

合久必婚 2024-09-07 08:24:34

与迄今为止的所有答案相反,在带有 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();
}

Contrary to all answers so far, on Linux with GCC (and I guess it is true for all modern POSIX operating systems), maximum stack size is a safety limit enforced by the operating system, that can be easily lifted.

I crafted a small program that calls recursively a function until at least 10 GB is allocated on stack, waits for input on the terminal, and then safely returns from all recursive calls up to 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();
}
叹梦 2024-09-07 08:24:34

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

This all depends on what language and compiler you use. But programs compiled with for instance C or C++ allocate a fixed size stack at program startup. The size of the stack can usually be specified at compile time (on my particular compiler it default to 1 MB).

小糖芽 2024-09-07 08:24:34

您没有提到哪种编程语言,但在 Delphi 中,编译选项包括最大和最小堆栈大小,我相信所有编译语言都存在类似的参数。

我当然不得不偶尔增加自己的最大值。

You don't mention which programming language, but in Delphi the compile options include maximum and minimum stack size, and I believe similar parameters will exist for all compiled languages.

I've certainly had to increase the maximum myself occasionally.

娇纵 2024-09-07 08:24:34

是的,大多数语言对堆栈大小都有限制。例如,在C/C++中,如果你有一个写得不正确的递归函数(例如不正确的基本情况),你就会溢出堆栈。这是因为,忽略尾递归,每次调用函数都会创建一个新的堆栈帧 占用堆栈上的空间。这样做足够多,你就会耗尽空间。

在 Windows (VS2008) 上运行此 C 程序...

void main()
{
    main();
}

...导致堆栈溢出:

Stack.exe 中 0x004113a9 处出现未处理的异常:0xC00000FD:堆栈溢出。

Yes, there is a limit on stack size in most languages. For example, in C/C++, if you have an improperly written recursive function (e.g. incorrect base case), you will overflow the stack. This is because, ignoring tail recursion, each call to a function creates a new stack frame that takes up space on the stack. Do this enough, and you will run out of space.

Running this C program on Windows (VS2008)...

void main()
{
    main();
}

...results in a stack overflow:

Unhandled exception at 0x004113a9 in Stack.exe: 0xC00000FD: Stack overflow.

剧终人散尽 2024-09-07 08:24:34

也许不是一个很好的答案,但可以让您更深入地了解 Windows 一般如何管理内存: 突破 Windows 的极限

Maybe not a really good answer, but gives you a little more in depth look on how windows in general manages the memory: Pushing the Limits of Windows

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文