char *ptr = (char*) malloc(40);
printf("%u",ptr);
56737856 (some output)
现在,如果我没记错的话,我们上面看到的输出不是物理地址,而是来自虚拟地址空间。我对么?
有没有办法查看实际的物理地址?或者反之亦然(如果我的上述假设是错误的),malloc 的所有内部实现是否都必须使用该jemalloc
算法?
您在用户空间应用程序中看到的所有地址都是虚拟地址。
物理地址只与内核有关。从虚拟地址到物理地址的映射很复杂,因为:
除了一些非常不寻常的情况(主要与弄乱硬件有关)之外,您不应该关心物理地址。
是的,在具有虚拟内存的平台上,它是进程地址空间中的地址,即它是虚拟内存中的地址。在这样的系统中,在典型的应用程序级别,RAM 中的实际物理地址没有任何意义——即使它当时已经知道,它也可以随时更改。物理 RAM 地址超出您的控制范围。因此,在典型的应用程序级别,当人们谈论“物理地址”时,他们通常指的是您打印的内容 - 进程地址空间中的地址,即虚拟地址。
只是不要使用%u
指针printf
。使用%p
. 或者至少将您的指针转换为适当大小的无符号整数类型并为该类型使用格式说明符。
有没有办法查看实际的物理地址?
在实模式下的 x86 架构上,没有内存保护,您可以取回实际的物理地址,因此您可以做一些愚蠢的事情,例如覆盖 0x0 地址。
这是来自“内存管理:C/C++ 中的算法和实现”的代码片段,它可能会使运行 DOS 的计算机崩溃:
void main()
{
unsigned char* ptr;
int i;
ptr = (unsigned char *)0x0;
for(i = 0; i < 1024; i++)
{
ptr[i]=0x0;
}
return;
}
如果我可以引用维基百科:
实模式不支持内存保护、多任务处理或代码特权级别。在引入保护模式的 80286 发布之前,实模式是 x86 CPU 唯一可用的模式。为了向后兼容,所有 x86 CPU 在复位时都以实模式启动。