因此,每当使用堆栈存储时,都需要手动解除分配,但如果使用堆,则会自动完成解除分配。
当您在函数中使用堆栈(函数中的局部变量)时,它们会在函数结束(返回)时自动释放。
当您从堆中分配时,分配的内存保持“正在使用”,直到它被释放。如果你不这样做,你的程序,如果它运行了足够长的时间并继续分配“东西”,将使用它所有可用的内存,并最终失败。
请注意,“stackfault”几乎不可能在应用程序中恢复,因为堆栈已满时不再可用,并且大多数“从错误中恢复”的操作将涉及使用一些堆栈内存。处理器通常有一个特殊的陷阱来从堆栈故障中恢复,但这会影响操作系统,如果操作系统确定应用程序已用完堆栈,它通常毫不留情 - 它只是立即“杀死”应用程序.
1.-假设我通过使用函数的无限迭代来运行具有递归解决方案的程序。理论上程序崩溃(堆栈溢出),但它会给计算机本身带来一些麻烦吗?(可能是 RAM 或 SO)。
不,计算机本身并不会因此受到伤害。如果您的程序没有保存用户正在处理的内容,当然可能会丢失数据。
除非硬件设计非常糟糕,否则很难编写对计算机造成任何损害的代码,除了丢失存储的数据(当然,如果您编写的程序从第一个扇区到最后一个扇区填满整个硬盘,您的数据将被您的程序填充磁盘的任何内容覆盖 - 这很可能导致机器无法再次启动,直到您在磁盘上重新安装操作系统)。但是 RAM 和处理器不会因错误的编码而损坏(幸运的是,大多数程序员时不时会犯错误)。
2.- 如果我忘记释放堆上的内存会发生什么。我的意思是,它只是给程序带来麻烦还是对计算机来说是永久性的。我的意思是这样的记忆可能永远不能再使用了。
一旦程序完成(并且大多数使用“太多内存”的程序确实会在某个时候以某种方式终止)。
当然,操作系统和其他应用程序处理“根本没有可用内存”的能力会有所不同。操作系统本身一般都可以,但是一些写得不好的驱动程序可能会崩溃,如果你不走运,会导致你的系统重新启动。由于没有足够的内存,应用程序更容易崩溃,因为当没有可用内存时,分配最终以 NULL(零)作为“返回地址”。在现代操作系统中使用地址零几乎总是会导致“分段错误”或类似问题(有关更多信息,请参见下文)。
但这些都是极端情况,大多数系统都设置成这样一个应用程序吞噬所有可用内存就会在系统的其余部分受到影响之前失败 - 并非总是如此,当然不能保证“导致”问题的应用程序是如果操作系统仅仅因为“消耗大量内存”而杀死应用程序,那么第一个被杀死的应用程序。Linux 确实有一个“内存不足杀手”,这是确保系统可以继续工作的一种非常激烈的方法[通过“工作”的某种定义]。
3.- 得到分段错误(堆)的问题是什么。
分段错误与堆没有直接关系。术语分段错误来自较旧的操作系统(Unix 风格),它们将内存的“段”用于不同的用途,而“分段错误”是指程序超出分配的段时。在现代系统中,内存被分成“页面”——通常每个 4KB,但一些处理器有更大的页面,并且许多现代处理器支持“大页面”,例如 2MB 或 1GB,用于大块内存.
现在,如果您使用的地址指向不存在(或不是“您的”)的页面,则会出现分段错误。这通常会在那时和那里结束应用程序。您可以“捕获”分段错误,但在我知道的所有操作系统中,尝试从这个“陷阱”继续是无效的 - 但您可以例如存储一些文件来解释发生的事情并帮助解决问题后来等等