欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

linux 内存管理(17) - 理解堆栈

程序员文章站 2022-04-26 12:27:51
...
  • 理解堆栈

1.概念

  一个由C/C++编译的程序占用的内存分为以下几个部分

  • 栈区:由编译器自动分配释放,存放函数的参数值,局部变量的值等。
  • 堆区:由程序员分配和释放,若程序员不释放,程序结束时可能由OS回收。
  • 全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量、未初始化的静态变量在相邻的另一块区域。
  • 文字常量区 : 常量字符串就是放在这里的。
  • 程序代码区 : 存放函数体的二进制代码。

2.源码分析:

    1 #include <stdlib.h>                                                                         
    2 #include <stdio.h>
    3 
    4 int n = 10;
    5 const int n1 = 20;
    6 int m;
    7 
    8 int main(){ 
    9     int s = 7; 
   10     static int s1 = 30;
   11     
   12     char *p = (char *)malloc(20);
   13     printf("global variable address=%p\n", &n);
   14     printf("const global address=%p\n", &n1);
   15     printf("global uninitialization variable address=%p\n", &m);
   16     
   17     printf("static variable address=%p\n", &s1);
   18     printf("stack variable address=%p\n", &s);
   19     printf("heap variable address=%p\n", p);
   20     
   21     pause();
   22 }

编译运行结果:

/Documents/work/code/memory$ gcc memory.c 
/Documents/work/code/memory$ ./a.out 
global variable address=0x601050
const global address=0x4006f8
global uninitialization variable address=0x60105c
static variable address=0x601054
stack variable address=0x7ffeaf17ce44
heap variable address=0xbdd010

打开另一个窗口,执行ps aux,找到 a.out对应的进程号,查看:

~$ cat /proc/5797/maps  
00400000-00401000 r-xp 00000000 08:01 1586299                            /home/zhaoxiao/Documents/work/code/albert/memory/a.out
00600000-00601000 r--p 00000000 08:01 1586299                            /home/zhaoxiao/Documents/work/code/albert/memory/a.out
00601000-00602000 rw-p 00001000 08:01 1586299                            /home/zhaoxiao/Documents/work/code/albert/memory/a.out
00bdd000-00bfe000 rw-p 00000000 00:00 0                                  [heap]
7fe74eb08000-7fe74ecc6000 r-xp 00000000 08:01 1847071                    /lib/x86_64-linux-gnu/libc-2.19.so
7fe74ecc6000-7fe74eec6000 ---p 001be000 08:01 1847071                    /lib/x86_64-linux-gnu/libc-2.19.so
7fe74eec6000-7fe74eeca000 r--p 001be000 08:01 1847071                    /lib/x86_64-linux-gnu/libc-2.19.so
7fe74eeca000-7fe74eecc000 rw-p 001c2000 08:01 1847071                    /lib/x86_64-linux-gnu/libc-2.19.so
7fe74eecc000-7fe74eed1000 rw-p 00000000 00:00 0 
7fe74eed1000-7fe74eef4000 r-xp 00000000 08:01 1847068                    /lib/x86_64-linux-gnu/ld-2.19.so
7fe74f0d4000-7fe74f0d7000 rw-p 00000000 00:00 0 
7fe74f0f2000-7fe74f0f3000 rw-p 00000000 00:00 0 
7fe74f0f3000-7fe74f0f4000 r--p 00022000 08:01 1847068                    /lib/x86_64-linux-gnu/ld-2.19.so
7fe74f0f4000-7fe74f0f5000 rw-p 00023000 08:01 1847068                    /lib/x86_64-linux-gnu/ld-2.19.so
7fe74f0f5000-7fe74f0f6000 rw-p 00000000 00:00 0 
7ffeaf15d000-7ffeaf17e000 rw-p 00000000 00:00 0                          [stack]
7ffeaf1cc000-7ffeaf1cf000 r--p 00000000 00:00 0                          [vvar]
7ffeaf1cf000-7ffeaf1d1000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

第一行:代码段

00400000-00401000 r-xp 00000000 08:01 1586299   /home/zhaoxiao/Documents/work/code/albert/memory/a.out

第三行:可读写,不可执行,为数据段,存储全局变量和静态变量;

00601000-00602000 rw-p 00001000 08:01 1586299                            /home/zhaoxiao/Documents/work/code/albert/memory/a.out

第四行:heap

00bdd000-00bfe000 rw-p 00000000 00:00 0                                  [heap]

第五行:stack

7ffeaf15d000-7ffeaf17e000 rw-p 00000000 00:00 0                          [stack]

变量和maps对应:

  • 栈变量s地址为:0x7ffeaf17ce44,位于进程栈段7ffeaf15d000-7ffeaf17e000;
  • p变量地址为:0xbdd010,位于进程堆段00bdd000-00bfe000;
  • 全局变量n(0x601050),m(0x60105c),静态变量s1(0x601054),位于数据段00601000-00602000;
  • 只读全局变量n1(0x4006f8),位于代码段00400000-00401000。

小结:
linux 内存管理(17) - 理解堆栈

相关标签: 内存管理