由于堆栈溢出,C中通常会发生什么?

时间:2017-01-13 12:24:32

标签: java c error-handling stack-overflow

在Java中,会有一个堆栈跟踪,表示StackOverflowError并且整个系统不会崩溃,只有程序崩溃。

在C中我意识到超出界限的数组索引会产生分段错误。对于C中的堆栈溢出是否相同,并且还存在分段错误,即类似问题的错误类型相同?

我没有测试C中有意识的无限复活,看看会发生什么,因为我不知道后果。

或者它有时候会更糟糕,C中的堆栈溢出可能会导致操作系统故障并迫使您重新启动电源以便重新启动?或者更糟糕的是,造成不可逆转的硬件损坏?堆栈溢出错误有多糟糕的影响?

似乎很清楚,Java中的保护比C中更好。在C中是否比在汇编/机器代码中更好,还是在C中作为汇编实际上是相同(缺乏)保护?

4 个答案:

答案 0 :(得分:6)

  

在C中我知道超出范围的数组索引会产生分段错误。对于C中的堆栈溢出是否相同,并且还存在分段错误,即类似问题的错误类型相同?

在C中无法保证 会出现分段错误。 C标准说它是undefined behaviour并且保留它。它可能表现得如何,取决于实现/平台。

  

或者它有时候会更糟糕,C中的堆栈溢出可能会导致操作系统故障并迫使您重新启动电源以便重新启动?或者更糟糕的是,造成不可逆转的硬件损坏?堆栈溢出错误有多糟糕的影响?

在现代操作系统中,很少有任何不幸发生在系统上;通常,只有程序会崩溃。现代操作系统使用various memory protection techniques

  

似乎很清楚,Java中的保护比C中更好。在C中是否比在汇编/机器代码中更好,还是在C中作为汇编实际上是相同(缺乏)保护?

那是因为在Java中,内存是“受管理的”。在C中,它留给程序员;它是设计。 C编译器最终生成机器代码;所以它不会更好或更糟。明显, 一个好的编译器可以检测到其中的一些问题并警告你,这与C语言相比具有优势。

答案 1 :(得分:4)

因为任何系统资源故障,内存故障的处理基本上都是由操作系统处理的,而不是语言本身。

排除某些特定的预防操作,作为堆栈检查,这类问题通常会触发可由语言运行时处理的操作系统异常。

如果启用了堆栈检查,通常在编译器命令行上指定一些开关,则指示编译器为每个堆栈消耗操作插入检查探测代码,以验证内存可用性。

默认情况下,由于任何原因,过度使用堆栈或损坏,执行尝试访问分配的堆栈空间范围之外的内存,OS会触发结构化异常。 Java尽可能多的C运行时通常会处理这些异常,并提供一些方法将它们传递给用户代码以便最终恢复(即通过信号或SEH)。如果没有从用户代码关联处理程序,则控件将传递给运行时,默认情况下将控制受控任务关闭(优雅关闭)。

如果没有可用的处理,即使从运行时也没有,操作系统将关闭任务并突然减少资源(即截断文件,关闭端口等)。

在任何情况下,操作系统都会保护系统,除非操作系统有缺陷...

在C中,注册一个保护可能失败的代码片段的处理程序是正常的。处理异常的方式取决于您的操作系统(即在Windows下,您可以包装可能在异常处理程序__try __except中失败的代码)。

答案 2 :(得分:3)

这不是C问题,至少发生的事情不是由C指定的.C只会说它是未定义的行为。因此效果是运行时的问题。在任何合理的操作系统上,这都会产生某种错误,并且* nixes会对您的进程产生分段错误。即使是异国情调的小型操作系统也可以保护自己免受错误处理。无论如何,这绝不会让操作系统崩溃。 Java不是更好而不是C,它们是不同的语言并且具有不同的运行时。从设计上讲,Java在某种意义上更安全,它可以保护您免受许多内存问题(等等)。 C使您可以更好地控制机器,是的,它或多或少是一种汇编语言。

答案 3 :(得分:3)

每个执行线程在运行时创建线程期间都分配了堆栈。如果在程序执行期间检测到堆栈溢出(编译本机程序),则只会影响程序(进程),而不会影响操作系统。