我正在按照简单的C程序运行:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv){
void *p = malloc(4);
fprintf (stderr, "p==%p\n", p);
return 0;
}
不同的运行会产生不同的结果:
点== 0x101c010
然后:p == 0x1ad9010
然后:p == 0xe77010
等等。
我记得,过去malloc是完全确定的。所以可能从某个版本开始,malloc会添加一些随机性。 我现在在Ubuntu上使用gcc-4.6.3。
有没有办法消除这种随机性?
答案 0 :(得分:9)
如果变化是由地址空间布局随机化引起的,那么,根据this page,您可以使用以下命令禁用它:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
这只应暂时用于调试目的。
这是一篇关于插入函数的好文章:Intercepting Arbitrary Functions on Windows, UNIX, and Macintosh OS X Platforms by Daniel S. Myers and Adam L. Bazinet。这将允许您使用完全受控的实现替换malloc
行为。
答案 1 :(得分:7)
首先,在C中绝对没有保证的内存管理器确定性。即使你看到它也不能依赖它,句号。
其次,现在许多环境主要使用地址布局随机化来确保各种缓冲区溢出的利用不能依赖于确定性地址,从而使用它们来执行任意代码。
答案 2 :(得分:0)
Malloc从操作系统获取内存,该内存分配未使用的内存。
将返回哪些地址将在很大程度上取决于计算机的先前使用。
答案 3 :(得分:0)
鉴于精确相同的条件,malloc()
的结果将始终相同。 (就像计算中的任何东西一样,没有真正的随机性。)但是,确定条件超出了程序的状态或控制范围。
答案 4 :(得分:0)
直接回答你的问题:没有。 malloc的C标准没有说明它是确定性的,所以实现者可以自由地编写它,他们认为它会使它最有效。
答案 5 :(得分:0)
给定的malloc
实现完全有可能在响应中具有确定性(通常在讨论malloc
的实现是否是“确定性”时,就人们所花费的时间而言关心,是否可以用于RT编程)。它取决于所使用的虚拟内存系统,代码本身,以及同一进程空间中其他代码对它或底层内存管理器的调用问题的确定性如何,但是给出所有这些的适当条件,你可以有一个确定性的malloc
。
尽管如此,没有理由说它应该是。毕竟,任何依赖于使用的特定地址的代码都可以忽略malloc
并直接写入内存 - 毕竟它知道它可以免费使用!
因此,由于维持这种确定性行为没有价值,如果它真的发生了,它纯粹是几种不同实现选择的意外,虽然它们会有点有趣(知道这样的实现是多么有趣)最终是确定性的)他们肯定不是人们所期望的。