Linux进程的五个段

来源:互联网 发布:java订单管理系统源码 编辑:程序博客网 时间:2024/05/29 03:55

下面我们来简单归纳一下进程对应的内存空间中所包含的5种不同的数据区都是干什么的。

1.代码段
代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存中的镜像。代码段需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作——它是不可写的。

2.数据段
数据段用来存放可执行文件中已初始化全局变量,换句话说就是存放程序静态分配的变量和全局变量。

3.BSS段
BSS段通常是指用来存放程序中未初始化的全局变量的一块内存区域,属于静态内存分配。BSS段包含了程序中未初始化的全局变量,在内存中BSS段全部置零。

4.堆(heap)
堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)它的物理内存空间是由程序申请的,并由程序负责释放。

5.栈
栈是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。它是由操作系统分配的,内存的申请与回收都由OS管理。

下面我们来看一看例子:

    //main.c    int a = 0; //全局初始化区    char *p1;  //全局未初始化区    int main(void)    {        static int c =0//全局(静态)初始化区        int b;            //栈        char s[] = "abc"; //栈        char *p2;         //栈        char *p3 = "123456";     //"123456\0"在常量区,p3在栈上。        p1 = (char *)malloc(10);        p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。        return 0;    }

总结
全局变量—>数据段
局部变量—>栈
静态全局—>数据段
静态局部—>数据段
指针 —>堆
未初始化全局—>bss段

下面有一个疑问,不知道对不对,请各位看官指点:

“`
char *cc()
{
char str[] = “hello”;
char *p= “world”;
return p;
}

问题
1. str存在哪里;
2. “hello”存在哪里;
3. *p存在哪里;
4. “world”存在哪里;

答疑
进程中的栈,是在进程运行时,分配的一块内存,生存期为进程运行的整个区间。 用来保存函数中的局部变量,以及函数的返回地址 这里 变量 str[] ,p都是局部变量, 在栈上 函数结束 函数内的局部变量就不可再用 栈上的局部变量都是在编译时明确知道大小的 。

char str[] = “hello”; 这个是在栈上占用一块6个字节的空间,把”hello” (五个字符和一个结束符’\0’) 从常量区复制过来 。

char *p= “world”; 这个是在栈上分配一个 char类型指针,直接指向常量区的字符串 “world”。

0 0
原创粉丝点击