c - 将数组放在堆上而不是堆栈上,是否可以消除段错误的可能性?

标签 c

这是我的问题。假设我的数组大小为 10,当我循环并将数组填充到 13 时,会出现段错误,因为我损坏了堆栈上的一些重要信息。如果我把它放在堆上,我是否可以免受段错误的影响?这更多的是一个概念性问题。

最佳答案

没有。如果超出分配的空间,则说明您正在使用不属于应用程序或属于应用程序其他部分的内存。

接下来发生的事情是未定义的。无论哪种情况,如果仅超出三个字节直接导致段错误,我都会感到惊讶 - 页面粒度并不小。段错误是处理器和操作系统的功能,而不是 C 语言的功能,当您访问未分配给进程的内存时,就会发生段错误。

在堆栈缓冲区溢出的情况下,您很可能会损坏当前或调用函数中的一些相邻数据,如果发生段错误,那将是由于对损坏的数据进行了操作,例如弹出无效返回例如,程序计数器的地址,而不是溢出本身。

类似地,如果您超出了堆分配,结果取决于您正在破坏的内容以及随后如何使用它。堆损坏特别隐蔽,因为错误的结果可能仍然未被检测到(潜在的),或者在代码的某些不相关区域中实际错误发生很久之后导致失败 - 通常是当您尝试释放或分配堆所在的其他分配时建筑物已被毁坏。您损坏的内存可能是其他现有分配的一部分,并且仅当使用损坏的数据时,错误可能才会显现出来。

您观察到的错误完全是非确定性的 - 在您所描述的情况下,立即出现段错误可能不太可能,但实际上这是您所希望的最好结果,因为所有其他可能的失败表现都特别困难进行调试。堆栈数据溢出导致的故障可能更加局部化 - 通常您会在函数内看到损坏的数据,或者函数返回时会失败,而堆错误通常不太明显,因为您正在损坏的数据可以关联与您的应用程序中的任何代码。如果该代码不运行或很少运行,您可能永远不会观察到任何失败,

问题的“解决方案”不是编写溢出的代码 - 它总是会出错,并且使用不同类型的内存分配并不能帮助您避免这种情况。使用简单地“隐藏”错误或使它们不那么明显或确定性的编码实践并不是一个好的策略。

关于c - 将数组放在堆上而不是堆栈上,是否可以消除段错误的可能性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58777298/

相关文章:

c - 在 while 循环中使用 getch()

c - Windows API 在 GetStdHandle() 中不起作用

c - 全行输入的极度麻烦。 C程序设计语言

c - C 中带有空格的字符串被截断

java - Java 谓词的 C/C++ 等价物

c - gcc 命令中的 .o 文件有什么作用?

c - 实现 if - else if 使用按位运算符

c++ - SDL2 - 未检测到操纵杆?

c - 标记一个 c 字符串

c - STM32F1xx CAN2 接收中断未被调用