C语言 是malloc/calloc从虚拟地址空间返回的内存地址


char *ptr = (char*) malloc(40);
printf("%u",ptr);
56737856 (some output)

现在,如果我没有错的话,我们上面看到的输出不是一个物理地址,而是来自虚拟地址空间。我说的对吗?

有办法看到实际的物理地址吗?或者反之亦然(如果我上面的假设是错误的),malloc的所有内部实现都必须使用jemalloc算法吗?

在用户空间应用程序中看到的所有地址都是虚拟地址。

物理地址只与内核有关。从虚拟地址到物理地址的映射是复杂的,如果:

    并不是所有的虚拟地址都有物理地址。(例如,未映射、惰性零填充或交换出的页面没有物理地址。)
  • 物理地址可能会在没有警告的情况下发生变化(例如,如果一个页面被换出和换回,或者如果一个共享页面被复制)。

除了一些非常不寻常的情况(主要是与硬件有关),您不应该关心物理地址。

是的,在具有虚拟内存的平台上,它是进程地址空间中的地址,即它是虚拟内存中的地址。在这样的系统中,在典型的应用程序级别上,RAM中的实际物理地址没有任何意义——即使当时已经知道了,它也可以随时改变。物理RAM地址超出了您的控制范围。因此,在典型的应用程序级别,当人们谈论"物理地址"时,他们通常指的是你打印的东西——进程地址空间中的地址,即虚拟地址。

就是不要使用%uprintf的指针。使用%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复位时都以实模式启动。

相关内容

  • 没有找到相关文章

最新更新