补充:你看到的所有地址都不是真的
写过打印出指针的 C 程序吗?你看到的值(一些大数字,通常以十六进制打印)是虚拟地址(virtual
address)。有没有想过你的程序代码在哪里找到?你也可以打印出来,是的,如果你可以打印它,它也
是一个虚拟地址。实际上,作为用户级程序的程序员,可以看到的任何地址都是虚拟地址。只有操作系
统,通过精妙的虚拟化内存技术,知道这些指令和数据所在的物理内存的位置。所以永远不要忘记:如
果你在一个程序中打印出一个地址,那就是一个虚拟的地址。虚拟地址只是提供地址如何在内存中分布
的假象,只有操作系统(和硬件)才知道物理地址。
这里有一个小程序,打印出 main() 函数(代码所在地方)的地址,由 malloc()返回的堆空间分配的
值,以及栈上一个整数的地址:
// 你所看到的所有地址都不是真的
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[]){printf("location of code:%p\n",(void *)main);printf("location of heap:%p\n",(void *)malloc(1));int x = 3;printf("location of stack:%p\n",(void *) &x);return x;
}
从这里,你可以看到代码在地址空间开头,然后是堆,而栈在这个大型虚拟地址空间的另一端。所有这些地址都是虚拟的,并且将由操作系统和硬件翻译成物理地址,以便从真实的物理位置获取该地址的值。
root@VM-24-6-centos justin1220]# ./13
location of code:0x40057d
location of heap:0x602010
location of stack:0x7fffffffe02c
main入口地址:0x40057d
heap起始地址:0x602010
stack起始地址:0x7fffffffe02c
ref:https://pages.cs.wisc.edu/~remzi/OSTEP/Chinese/13.pdf