是否有处理堆栈溢出的定义行为?

除了终止进程之外,似乎没有什么可以做的。我只是想知道是否有人知道 C 标准对此有何规定。

有帮助吗?

解决方案

在标准不要求使用堆叠的,并没有什么可说栈溢出。

其他提示

C99标准没有定义堆叠;它仅讨论了抽象的自动或分配的存储,而用溢出检测的连续堆只有一个机构用于实现自动存储。

标准的第7.14节SIGSEGV定义为其中发生上“的非法访问存储”的信号。的C实现并不需要产生的任何信号,但如果检测到堆栈溢出用的连续固定大小栈实现*通常信号SIGSEGV。

可以注册SIGSEGV的信号处理函数,但它不能返回 - “[I] f和函数返回时,如果Sig的值是SIGFPE,SIGILL,SIGSEGV,或任何其他实施对应于计算异常-defined值,则behavio [U] r被未定义“

(*不,我已经明知与C实现哪些没有工作,但我不知道在C标准防止使用用于实现在其他环境中可扩展的自动存储领域的普通技术的任何东西)

C标准甚至不限定堆叠,所以它当然不限定了什么情况的堆栈溢出时。

这里的答案是正确的,应该说它是无关的C标准,但你的声明说:“除了终止进程,它似乎并不像有一大堆可以做”是不是 - 如一个一般性 - 真

在事实上,在与虚拟内存管理和按需寻呼大多数系统中,分配的堆栈是相当小的(通常4KB比当前正在使用更多)和经常溢出(其产生一个缺页中断)和OS只是添加的存储器的另一页的栈的线程。

的栈限制 - 通常是 - 1MB,只是选择,以防止失控的程序和通常相当任意的图中没有一个绝对的限制(尽管它是在使用Intel处理器IIRC一些存储器型号)。这将通常没有意义的分配的物理存储器1MB给每个线程。

根据一些答案 这个问题, ,C 标准甚至没有提及堆栈的存在,更不用说堆栈溢出了。

我相当肯定发生了什么但是由操作系统定义的细节,在所有情况下,程序应该退出。你是在假设真的有什么,一旦发生堆栈溢出(至少作为一个程序员),你可以做的是正确的。所有你能做的,只能是防止他们在第一时间发生的事情。

这是给操作系统。许多操作系统允许覆盖默认堆栈大小,虽然。例如,在Windows上,您可以使用这个链接器标志增大从1MB堆栈大小为更高的值。

至于其他人都提到,标准不说的堆栈什么。

不过,我认为它是定义堆栈溢出的行为,标准会说这会导致不确定的行为。

::边敲击::

在某些系统上,确保任何可预见的青睐堆栈溢出后会增加相当大的开销,每个函数调用;因此,标准相当合理认为堆栈溢出未定义行为。这是完全适当的,如果目标是最大化与一个实现可以运行合法程序的效率。

在标准也并不要求系统有足够的栈,支持的函数调用任何非平凡的深度。考虑到一些有用的程序(尤其是在嵌入式系统世界)可以小于16个字节的栈获得通过,并且不一定能够腾出任何比这更多的内存,需要一个慷慨的堆栈将违反唐”的理念, “T付你不需要的东西。”

不幸的是,事实上,有没有办法让一个程序来谈谈什么样的深度,它需要什么,也没有询问什么样的堆栈是可用的,它不能保证唯一的方案,以从事未定义行为是那些其堆栈使用是最低保障的下方;嵌入式系统世界之外,基本上意味着标准保证一无所知任何程序比玩具大。

C标准是在这方面的矛盾。考虑下面的程序:

void foo(uintptr_t n)
{
    int a;
    printf("%p\n", (void *)&a);
    if (n+1) foo(n+1);
}
int main()
{
    int a;
    printf("%p\n", (void *)&a);
    foo(0);
}

此程序是完全符合的,不违反任何最低限度的翻译,和其他人所说,没有什么关于堆栈限制/溢出标准的语言。然而,它产生UINTPTR_MAX + 2个对象a(在每次调用电平),而实粒子全部重叠,每个都有不同的地址。这通过仅计数参数是不可能的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top