我们是否有一个示例演示由于C中错误的malloc大小而导致的非确定性失败?
例如,在linux中的'gzip'程序中:
.
.
.
char* a = (char*)malloc(256) // correct version
is changed to
char* a = (char*)malloc(206) //faulty version
.
.
.
因此,传递正确版本的测试用例tc在故障版本上失败(即,分段错误)。 但是,失败是不确定的。有时,故障版本上的失败测试用例tc不会导致分段错误(即通过)。
这可能是由于malloc的“未定义”行为,但我不知道它是如何发生的。
有人能给我一些具体的例子吗? 提前谢谢。
答案 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标准说:
未定义的行为
行为,在使用不可移植或错误的程序结构或错误数据时, 本国际标准没有要求
这意味着任何都可能发生。你无法预测结果,必须始终避免这种情况。