在Java中,会有一个堆栈跟踪显示StackOverflowError和整个系统不会崩溃,只有程序会崩溃。
在C中,我知道超出界限的数组索引将产生分段错误。C中的堆栈溢出是否相同,也会出现分割错误,也就是对于类似的问题也存在相同的错误类型?
我没有在C中测试一个有意识的无限循环,因为我不知道结果会发生什么。
或者,有时情况更糟,C中的堆栈溢出会导致操作系统故障,并迫使您重新启动电源周期吗?或者更糟糕的是,造成不可逆转的硬件破坏?堆栈溢出错误会有多坏的影响?
很明显,Java中的保护优于C中的保护,C中的保护是否比汇编/机器代码好,或者C中的保护实际上与程序集相同(缺乏)?
发布于 2017-01-13 12:41:32
在C中,我知道超出界限的数组索引将产生分段错误。C中的堆栈溢出是否相同,也会出现分割错误,也就是对于类似的问题也存在相同的错误类型?
在C语言中,不能保证会出现分割错误。C标准说它是https://en.wikipedia.org/wiki/Undefined_behavior,就这样吧。这到底是如何表现出来的,完全取决于实现/平台。
或者,有时情况更糟,C中的堆栈溢出会导致操作系统故障,并迫使您重新启动电源周期吗?或者更糟糕的是,造成不可逆转的硬件破坏?堆栈溢出错误会有多坏的影响?
在现代操作系统中,很少有任何不正常的事情发生在系统上;通常,只有程序会崩溃。现代操作系统使用各种内存保护技术。
很明显,Java中的保护优于C中的保护,C中的保护是否比汇编/机器代码好,或者C中的保护实际上与程序集相同(缺乏)?
这是因为在Java中,内存是“管理的”。在C语言中,它是留给程序员的;它是由设计完成的。C编译器最终会生成机器代码,所以它不会更好或更糟。显然,一个好的编译器可以检测到其中的一些问题并对您进行警告,这与程序集相比在C中是一个优势。
发布于 2017-01-13 12:42:44
对内存故障的处理,就像任何系统资源故障一样,基本上是由操作系统来处理的,而不是语言本身。
除了某些特定的预防操作(如堆栈检查)外,此类问题通常会触发操作系统异常,该异常可以由语言运行时处理。
如果启用堆栈检查(通常在编译器命令行上指定某些开关),则指示编译器为每个堆栈消耗操作插入检查探测代码,以验证内存可用性。
默认情况下,当由于任何原因,过度使用堆栈或损坏时,执行尝试访问分配的堆栈空间界限外的内存操作系统触发结构化异常。Java和许多C运行时一样,通常处理这些异常,并提供某种方式将它们传递给用户代码,以便最终恢复(即通过signal或SEH)。如果用户代码中没有关联处理程序,则将控件传递给运行时,默认情况下,运行时将管理受控的任务关闭(优雅的关闭)。
如果没有可用的处理,甚至运行时没有处理,操作系统将关闭任务并突然操作资源释放(即截断文件、关闭端口等)。
在任何情况下,操作系统都会保护系统,除非操作系统有缺陷.
在C中,正常情况下注册一个处理程序来保护可能失败的代码片段。处理异常的方式取决于操作系统(即,在windows下,可以将可能在异常处理程序__try __except中失败的代码包装起来)。
发布于 2017-01-13 12:39:01
这不是C问题,至少C不指定发生的事情,C只会说它是未定义的行为。因此,效果是运行时的问题。在任何合理的操作系统上,这将产生某种错误,将被捕获,并且在*nixes中将产生一个分割错误到您的进程。即使是异国情调的小型OSes也会保护自己不受错误过程的影响。不管怎么说,这绝不会让操作系统崩溃。Java并不比C好,它们是不同的语言,具有不同的运行时。从设计上看,Java更安全,因为它将保护您免受许多内存问题(以及其他问题)的影响。C让您更好地控制机器,是的,它或多或少是一种汇编语言。
https://stackoverflow.com/questions/41634610
复制相似问题