不正确的malloc大小导致的不确定性失败?

时间:2013-10-03 12:12:51

标签: c linux segmentation-fault malloc non-deterministic

我们是否有一个示例演示由于C中错误的malloc大小而导致的非确定性失败?

例如,在linux中的'gzip'程序中:

.
.
.
char* a = (char*)malloc(256) // correct version 
is changed to
char* a = (char*)malloc(206) //faulty version
.
.
.

因此,传递正确版本的测试用例tc在故障版本上失败(即,分段错误)。 但是,失败是不确定的。有时,故障版本上的失败测试用例tc不会导致分段错误(即通过)。

这可能是由于malloc的“未定义”行为,但我不知道它是如何发生的。

有人能给我一些具体的例子吗? 提前谢谢。

2 个答案:

答案 0 :(得分:3)

将内存想象成一系列页面。有些是可用于您的进程的,有些是由于权限而不可用,有些只是无法访问,即未映射。请考虑此地图(不按比例):

      +                        +   +
      |   Page, 4096 bytes     |   |
      +-----------------+------+   |
      |                 |      |   |
      |                 |      |   |
      |                 |      |   |
      +-----------------+------+-->v
           3890B          206B   X <-- Not mapped, can't touch!

如果你分配206个字节,那么它全部取决于页面中206个字节所在的位置。

  • 如果它们位于开头(向左),则访问更多是可以的 Linux是关注的(但就C而言仍然是未定义的行为)

  • 但是,如果访问更多字节溢出到另一个页面,则使用其他页面 保护或未映射到的,Linux将不会被逗乐,你会得到一个段错误

所以你受到无法控制的东西的摆布:malloc将分配你的数据,即额外的50个字节。

答案 1 :(得分:1)

它不是malloc的未定义行为。它只是给你你要求的记忆。

您可能稍后访问非保留内存(类似a[208] = 'x';),这将导致未定义的行为。

C标准说:

  

未定义的行为

     

行为,在使用不可移植或错误的程序结构或错误数据时,   本国际标准没有要求

这意味着任何都可能发生。你无法预测结果,必须始终避免这种情况。