Linux程序内存空间布局以及实战

一 典型内存空间布局

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分配的堆则在这些内存之上,并向上生长。