c++ - C++ 中堆栈溢出和段错误的危险

标签 c++ segmentation-fault stack-overflow

我试图了解对象(变量、函数、结构等)在 C++ 中是如何工作的。在这种情况下,我看到基本上有两种存储方式:堆栈和堆。因此,无论何时使用堆存储都需要手动解除分配,但如果使用堆栈,则解除分配是自动完成的。所以我的问题与不良做法可能导致程序本身或计算机的问题有关。例如:

1.- 让我们假设我通过使用函数的无限迭代运行具有递归解决方案的程序。理论上程序会崩溃(堆栈溢出),但是会不会对计算机本身造成一些麻烦? (可能到 RAM 或到 SO)。

2.- 如果我忘记释放堆上的内存会发生什么。我的意思是,它只是给程序带来麻烦,还是对计算机来说是永久性的。我的意思是可能是这样的内存再也不能使用了。

3.- 出现段错误(堆)的问题是什么。

欢迎其他一些与此相关的危险或关心。

最佳答案

Accordingly, whenever the stack storage is used it needs to be dealocated manually, but if the heap is used, then the dealocation is automaticcally done.



当您使用堆栈 - 函数中的局部变量 - 当函数结束(返回)时,它们会自动解除分配。

当您从堆中分配时,分配的内存将保持“正在使用”状态,直到被释放。如果你不这样做,你的程序,如果它运行足够长的时间并继续分配“东西”,将使用所有可用的内存,并最终失败。

请注意,在应用程序中几乎不可能从“堆栈错误”中恢复,因为堆栈已满时不再可用,并且大多数“从错误中恢复”的操作将涉及使用一些堆栈内存。处理器通常有一个特殊的陷阱来从堆栈错误中恢复,但这会影响操作系统,如果操作系统确定应用程序已经用完堆栈,它通常毫不留情——它只是立即“杀死”应用程序.

1.- Let'suposse that I run a program with a recursion solution by using an infinite iteration of functions. Theoretically the program crashes (stack overflow), but does it cause some trouble to the computer itself? (To the RAM maybe or to the SO).



不,计算机本身并不会因此而受到损害。如果您的程序没有保存用户正在处理的内容,当然可能会丢失数据。

除非硬件设计得很糟糕,否则很难编写对计算机造成任何损害的代码,除了丢失存储的数据(当然,如果你编写一个程序,从第一个扇区到最后一个扇区填满整个硬盘,您的数据将被您的程序填充磁盘的任何内容覆盖 - 这很可能导致机器无法再次启动,直到您在磁盘上重新安装操作系统)。但是 RAM 和处理器不会被糟糕的编码损坏(幸运的是,因为大多数程序员时不时会犯错误)。

2.- What happens if I forget to dealocate memory on the heap. I mean, does it just cause trouble to the program or it is permanent to the computer in general. I mean it might be that such memory could not be used never again or something.



一旦程序完成(并且大多数使用“太多内存”的程序确实会以某种方式终止,在某些时候)。

当然,操作系统和其他应用程序处理“根本没有可用内存”的情况略有不同。操作系统本身一般是可以的,但一些写得不好的驱动程序可能会崩溃,如果你不走运,会导致你的系统重新启动。由于没有足够的内存,应用程序更容易崩溃,因为当没有可用内存时,分配以 NULL(零)作为“返回地址”。在现代操作系统中使用地址零几乎总是会导致“段错误”或类似问题(有关更多信息,请参见下文)。

但这些都是极端情况,大多数系统都设置为一个应用程序占用所有可用内存会在系统的其余部分受到影响之前失败 - 并非总是如此,并且当然不能保证“导致”问题的应用程序是如果操作系统仅仅因为“占用大量内存”而杀死应用程序,则第一个被杀死。 Linux 确实有一个“内存不足杀手”,这是一种非常严厉的方法来确保系统可以继续工作 [根据“工作”的某些定义]。

3.- What are the problems of getting a segmentation fault (the heap).



段错误与堆没有直接关系。术语段错误来自较旧的操作系统(Unix 风格),该操作系统将内存“段”用于不同的用途,“段错误”是指程序超出分配的段时。在现代系统中,内存被分成“页面”——通常每个 4KB,但有些处理器有更大的页面,许多现代处理器支持“大页面”,例如 2MB 或 1GB,用于大 block 内存.

现在,如果您使用的地址指向不存在(或不是“您的”)的页面,则会出现段错误。这通常会在那时和那里结束应用程序。您可以“捕获”段错误,但在我所知道的所有操作系统中,尝试从这个“陷阱”继续是无效的 - 但是您可以例如存储一些文件来解释发生的事情并帮助解决问题后来等等。

关于c++ - C++ 中堆栈溢出和段错误的危险,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14367225/

相关文章:

C++ 函数常量

c++ - 文件无法打开,在调试器之外运行会导致段错误 (c++)

c - 段错误 - 试图将二进制文件读入内存

检查结构中的指针是否为 NULL

c++ - 如何实现指向其他多类型 vector 的 C++ vector ?

c++ - 类型转换 c++, quadmath

c++ - 使用 find 函数,如何在 C++ 上使用 multimap 找到某个键​​的最后一次出现(而不是第一次出现)?

.net - 为什么使用 NUnit/TestDriven.Net2.0 测试会崩溃?

ruby - 对于最大的回文乘积问题(Project Euler),递归中的堆栈级别太深

exception - vb.net 中的 StackOverFlow 异常是什么?