无限的“吗?

关于堆栈分配有许多相关的问题是可以理解的

什么和堆栈和堆在哪里?

为什么堆栈大小有限制?

堆栈和堆内存的大小

但是,在各种* nix机器上,我可以发出bash命令

ulimit -s unlimited

或csh命令

set stacksize unlimited

这如何改变程序的执行方式? 对程序或系统性能有任何影响(例如,为什么这不是默认设置)?

如果有更多的系统细节是相关的,我主要关心在x86_64硬件上运行的Linux上使用GCC编译的程序。


这会有些迂腐,有些你可能已经知道了,所以请耐心等待。 当你在程序中声明变量时,内核会为堆栈中的数据分配空间。 你可以告诉内核限制任何给定程序可以使用的堆栈空间(或堆,或堆),这样一个程序不能占用整个堆栈。 如果程序可以使用的堆栈的数量没有限制,那么通常会导致程序崩溃的错误会导致整个系统崩溃。 内核崩溃的程序高于分配的堆栈空间称为“堆栈溢出”。

堆栈中最常见的错误之一是过度递归或无限递归。 由于每次对函数的新调用都会将其所有变量放在堆栈中,因此非尾优化的递归程序可以快速耗尽由内核分配给进程的堆栈空间。 例如,这个无限递归函数一旦超出了分配的堆栈空间就会导致内核崩溃:

int smash_the_stack(int number) {
    smash_the_stack(number + 1);

    return 0;
}

传统上,堆栈空间耗尽是一件非常可怕的事情,因为它可以用于“堆栈粉碎”或堆栈缓冲区溢出的情况。 当恶意用户故意导致堆栈溢出来更改堆栈指针以执行他们自己的任意指令而不是您自己的代码中的指令时,会发生这种情况。

就表现而言,不应有任何影响。 如果你通过递归来达到堆栈限制,那么堆栈大小可能不是最好的解决方案,但是否则它不是你应该担心的。 如果一个程序绝对必须存储海量数据,它可以使用堆来代替。


过失,堆栈大小的确可以是无限的。 _STK_LIM是默认值, _STK_LIM_MAX每个架构_STK_LIM_MAX所不同,从include/asm-generic/resource.h可以看出:

/*
 * RLIMIT_STACK default maximum - some architectures override it:
 */
#ifndef _STK_LIM_MAX
# define _STK_LIM_MAX           RLIM_INFINITY
#endif

从这个例子可以看出,通用值是无限的,其中RLIM_INFINITY又是一般情况下定义为:

/*
 * SuS says limits have to be unsigned.
 * Which makes a ton more sense anyway.
 *
 * Some architectures override this (for compatibility reasons):
 */
#ifndef RLIM_INFINITY
# define RLIM_INFINITY          (~0UL)
#endif

所以我猜想真正的答案是 - 堆栈大小可以受限于某种体系结构,那么无限制的堆栈跟踪将意味着无论_STK_LIM_MAX被定义_STK_LIM_MAX ,并且万一它是无穷大的 - 它是无限的。 有关将其设置为无限及其含义的含义的详细信息,请参阅另一个答案,它比我的要好。


“ulimit -s unlimited”可以让堆栈无限增长。 如果你通过递归编写程序,这可能会阻止你的程序崩溃,尤其是如果你的程序不是尾递归的(编译器可以“优化”那些),并且递归深度很大。

@Maxwell Hansen的回答几乎包含了对这个问题的正确答案。 然而,它被深埋在许多虚假的声明中 - 请参阅评论。 因此,我觉得有义务写这个答案。

链接地址: http://www.djcxy.com/p/14089.html

上一篇: s unlimited" do?

下一篇: How is the initial value of the stack pointer determined?