0

我们是否有一个示例说明由于 C 中的 malloc 大小不正确而导致的非确定性故障?

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

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

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

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

谁能给我一些具体的例子?先感谢您。

4

2 回答 2

3

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

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

如果您分配 206 个字节,这一切都取决于这 206 个字节在页面中的位置。

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

  • 然而,如果访问更多字节溢出到另一个页面,具有不同的保护或没有映射到一个页面,Linux 将不会被逗乐,你会得到一个段错误

所以你受制于一些你无法控制的事情:malloc将你的数据分配到哪里,即额外的 50 个字节将在哪里。

于 2013-10-03T12:21:51.860 回答
1

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

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

C标准 说:

未定义的行为

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

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

于 2013-10-03T12:17:04.867 回答