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

时间:2013-06-08 17:03:45

标签: c linux malloc

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

56737856 (some output)

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

有没有办法查看实际的实际地址?反之亦然(如果我的上述假设是错误的),并且malloc的所有内部实现都必须使用jemalloc算法吗?

3 个答案:

答案 0 :(得分:11)

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

物理地址只与内核有关。从虚拟地址到物理地址的映射很复杂,因为:

  • 并非所有虚拟地址都有物理地址。 (例如,未映射,懒惰零填充或换出的页面没有物理地址。)
  • 物理地址可能会在没有警告的情况下发生变化(例如,如果页面被换出并重新登录,或者复制了共享页面)。

在一些非常不寻常的情况之外(主要是与硬件混乱),你不应该关心物理地址。

答案 1 :(得分:2)

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

只是不要将%u用于printf指针。使用%p。或者至少将指针转换为适当大小的无符号整数类型,并使用该类型的格式说明符。

答案 2 :(得分:0)

  

有没有办法查看实际的实际地址?

real mode的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在重置时都以实模式启动。