2011-05-28 145 views
3

有没有办法纠正失败的静态分配或程序运行时只是通过分段或总线故障失败?感谢:检查堆栈分配是否失败?

帖子是由C99如何让疯狂的东西就像char text[n];

编辑启发。我现在明白粗体的部分不是静态分配。所以只是为了检查,如果像char text[1234];失败,可能的恢复策略是相同的?

+1

这不是静态分配。这是在堆栈上。如果你认为它可能会失败,那么使用堆。 – 2011-05-28 21:01:55

+0

这不是静态分配。 – 2011-05-28 21:02:58

+0

用'反引号'代码,而不是**双星号**。 – 2011-05-28 21:33:47

回答

1

您或许可以捕捉到信号,但您可以做的其他事情不多。当然,在使用它之前检查n以确保它具有合理的价值可以立即解决这个问题。

+0

信号,好主意...... – ImJustALittleCatfish 2011-05-28 20:57:33

+3

@ImJustALittleCatfish **危险,威尔罗宾逊!**请不要相信信号是一个好主意。信号总是一个坏主意(整本书可以写出信号和异步信号不安全如何使编程复杂化)。 – cnicutar 2011-05-28 20:59:45

+0

嗯,“复杂”和“坏”之间有区别。但我可以想象为什么用这种方式使用信号会很麻烦。 – ImJustALittleCatfish 2011-05-28 21:06:36

3

char text[n]在堆栈上分配一个可变大小的数组。它只需要将堆栈指针递增n

如果发生堆栈溢出,用户空间进程可以做的事情并不多 - 这取决于操作系统向进程发送信号并终止进程或调整堆栈大小。

+1

'libsigsegv'有许多平台的堆栈溢出处理程序。 – 2011-05-28 21:14:05

+0

@Chris:推荐更多1980年代风格的“便携式凭借对每个已知系统具有特定系统的黑客”的代码... ;-) – 2011-05-28 22:15:23

+0

@R .. - 我没有说它是好的,只是它可能是相关的。出于这个原因,我不会首先使用VLA。 – 2011-05-28 23:42:35

1

永远不要检查你不知道如何处理的错误情况。

说真的,你打算做什么?只有一小部分函数可以从信号处理程序中调用(请参阅man 7 signal),而printf和longjmp(longjmp是我能想到从这种问题中恢复的唯一方式)不是其中的一个。如果你想要重新执行这个过程,你可能会有一个保姆来完成这项工作,并避免混乱。

注意根据man alloca你实际上并没有被告知“分配”失败,当你尝试访问坏内存时,你只是得到一个SIGSEGV,当然这可能不会发生在文本[]数组中所有的,或者甚至没有在分配文本[]的函数中。

虽然以上两段是基于Linux的,但总体理论对于所有平台都是正确的。

使用malloc并有干净的处理。理智吧。

[编辑]

其实有尝试做到这一点的一种方式,那就是通过计算堆栈的开始(在主记录叠层)和堆栈限制(希望操作系统不会用完页)。然后在你做大堆栈分配之前,你可以计算你到底有多近。给你一个慷慨的摆动室,并在你分配之前失败。

+1

只要您可以确保在调用信号处理程序时没有运行异步信号不安全的函数,则来自信号处理程序*的'longjmp'是有效的。确切地说,是 – 2011-05-28 22:14:15

+0

@R。但是,你很少能知道这一点。任何SIGSEGV出于任何原因都会导致该问题。但让我们假设完美的编程,并且在大量分配之前没有功能会导致问题。你必须确保函数中的大分配*和它调用的任何函数都不会调用不安全的函数。虽然实际上完美的程序员文本让我觉得这应该作为犯罪前处理。更新了答案。 – 2011-05-28 22:39:27

0

这是一个堆栈分配而不是静态。失败模式是堆栈溢出。堆栈溢出的最合理策略是将其视为终端。

设计你的代码,使它不会溢出堆栈,而不是试图使它适应堆栈溢出。