浅析linux下c程序堆栈分布
我们知道c语言中的程序中的数据根据分布一般可以分为三种,一种是分布在数据段中的,一种是分布在栈上的,还有一种分布是堆上。全局变量往往都存放在数据段中,而函数中声明的变量一般都存放在栈上,而用malloc或者calloc分配出来的空间则是在堆上。但是我之前一直不知道这数据段、堆还有栈到底在内存上是怎样分布的,更不知道它们之间的距离是多少,也不会根据数据的指针来判断数据的类型。但是前些日子,为了跟踪一个数据莫名被修改的问题,终于对这堆栈的分布有了个形象的了解。
在《UNIX环境高级编程》中提到:对于x86处理器上的Linux,正文段从0x08048000单元开始,栈底则在0xC0000000之下开始(在这种特定结构中,栈从高地址向低地址方向增长)。堆顶和栈底之间未用的虚地址空间很大。
linux很多时候并不是跑在x86处理器上,除了这句话,我们还可以借助linux下的一个临时文件来查看堆栈的分布。那就是/proc/{pid}/maps这个文件,查看这个文件,可以看到相应进程的内存布局。我就是通过这个文件查到最终的内存布局的。如下图:
堆和栈之间的共享数据段和程序段一般会有很多,而栈和堆隔的也非常远。当看到一个指针指向的地址是0xbe开头的,基本就可以确定是在栈上存放的数据了,而指针非常小的,则不是在正文数据段就是在堆上。非常方便。