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下查看进程内存的使用情况
-
【原创】(十三)Linux内存管理之vma/malloc/mmap
-
详解Linux内核内存管理架构
-
【原创】(十)Linux内存管理 - zoned page frame allocator - 5
-
【原创】(十四)Linux内存管理之page fault处理
-
【原创】(八)Linux内存管理 - zoned page frame allocator - 3
-
Linux内核设备驱动之内存管理笔记整理
-
【原创】(十二)Linux内存管理之vmap与vmalloc
-
【原创】(九)Linux内存管理 - zoned page frame allocator - 4
-
Linux系统基本的内存管理知识讲解