Linux程序内存空间布局以及实战
一 典型内存空间布局
1 代码段(.txtt segment):代码段通常是指存放程序执行代码的一块内存区域。
2 初始化数据段(.data segment):通常是指用来存放程序已初始化的全局变量的一块内存区域。
3 未初始化数据段(.bss segment):通常是用来存放程序未初始化的全局变量的一块内存区域。
4 堆(heap):堆是用于存放进程运行中被动态分配内存段,它的大小并不固定,可动态地扩张或收缩。当进程调用malloc/free等函数分配内存时,新分配的内存就会被动态添加到堆上或释放内存从堆上被剔除。
5 栈(stack):栈又称堆栈,存放程序的局部变量(但不包括static声明的变量,static声明的变量在数据段)。
二 查看栈的大小
[[email protected] charpter05]# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 3884
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
# 此字段表示栈的大小
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 3884
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
三 实战
1 代码
#include<stdio.h>
#include<stdlib.h>
int g1=0, g2=0, g3=0;
int max(int i)
{
int m1=0,m2,m3=0,*p_max;
static int n1_max=0,n2_max,n3_max=0;
p_max = (int*)malloc(10);
printf("打印max程序地址\n");
printf("in max: %x\n\n",max);
printf("打印max传入参数地址\n");
printf("in max: %x\n\n",&i);
printf("打印max函数中静态变量地址\n");
printf("%x\n",&n1_max); //打印各本地变量的内存地址
printf("%x\n",&n2_max);
printf("%x\n\n",&n3_max);
printf("打印max函数中局部变量地址\n");
printf("%x\n",&m1); //打印各本地变量的内存地址
printf("%x\n",&m2);
printf("%x\n\n",&m3);
printf("打印max函数中malloc分配地址\n");
printf("%x\n\n",p_max); //打印各本地变量的内存地址
if(i) return 1;
else return 0;
}
int main(int argc, char **argv)
{
static int s1=0, s2, s3=0;
int v1=0, v2, v3=0;
int *p;
p = (int*)malloc(10);
printf("打印各全局变量(已初始化)的内存地址\n");
printf("%x\n",&g1); //打印各全局变量的内存地址
printf("%x\n",&g2);
printf("%x\n\n",&g3);
printf("======================\n");
printf("打印程序初始程序main地址\n");
printf("main: %x\n\n", main);
printf("打印主参地址\n");
printf("argv: %x\n\n",argv);
printf("打印各静态变量的内存地址\n");
printf("%x\n",&s1); //打印各静态变量的内存地址
printf("%x\n",&s2);
printf("%x\n\n",&s3);
printf("打印各局部变量的内存地址\n");
printf("%x\n",&v1); //打印各本地变量的内存地址
printf("%x\n",&v2);
printf("%x\n\n",&v3);
printf("打印malloc分配的堆地址\n");
printf("malloc: %x\n\n",p);
printf("======================\n");
max(v1);
printf("======================\n");
printf("打印子函数起始地址\n");
printf("max: %x\n\n",max);
return 0;
}
2 编译运行
[[email protected] charpter05]# g++ 0507.cpp -o 0507
[[email protected] charpter05]# ./0507
打印各全局变量(已初始化)的内存地址
601048
60104c
601050
======================
打印程序初始程序main地址
main: 4007a9
打印主参地址
argv: 2d7296d8
打印各静态变量的内存地址
601060
601064
601068
打印各局部变量的内存地址
2d7295e4
2d7295e0
2d7295dc
打印malloc分配的堆地址
malloc: 8d2010
======================
打印max程序地址
in max: 40067d
打印max传入参数地址
in max: 2d72958c
打印max函数中静态变量地址
601054
601058
60105c
打印max函数中局部变量地址
2d7295a4
2d7295a0
2d72959c
打印max函数中malloc分配地址
8d2030
======================
打印子函数起始地址
max: 40067d
[[email protected] charpter05]#
3 说明
从运行结果可以看到下面2个特点
1 传入的参数,局部变量,都是在栈顶分布,随着子函数的增多而向下增长。
2 函数的调用地址(函数运行代码),全局变量,静态变量都是在分配内存的底部存在,而malloc分配的堆则在这些内存之上,并向上生长。