c语言 linux sd_linux c语言下的堆、栈、数据段、代码段分别存的是啥东西!

78a611bf07e5c2f664cab2e38915dd45.png

asd8532

进 程(执行的程序)会占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等。不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内存是事先静态分配和统一回收的,而有些却是按需要动态分配和回收的。对任何一个普通进程来讲,它都会涉及到5种不同的数据段(如代码段,数据段,BSS段,堆段,栈段)。在进程被载入内存中时,基本上被分裂成主要的6个小的节(section)---如, .text节, .data节, .bss节, 堆节, 栈节, 环境/参数节.  一、Linux进程的五个段下面我们来简单归纳一下进程对应的内存空间中所包含的5种不同的数据区都是干什么的。 重点:代码段、数据段、堆栈段,这是一个概念堆、栈、全局区、常量区,这是另一个概念  1)代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存中的镜像。代码段需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作——它是不可写的。代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。 2)数据段:数据段用来存放可执行文件中已初始化全局变量,换句话说就是存放程序静态分配的变量和全局变量。 3)BSS段:BSS段包含了程序中未初始化的全局变量,在内存中 bss段全部置零。BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。 4)堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)它的物理内存空间是由程序申请的,并由程序负责释放。 5)栈:栈又称堆栈,栈是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。   它是由操作系统分配的,内存的申请与回收都由OS管理。 举个具体的C语言的例子吧://main.cint a = 0; //全局初始化区char *p1; //全局未初始化区main(){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字节的区域就在堆区。}  二、各个段在内存中的组织各个段段在线性空间中的组织。直接上图:+--------------------------------   高地址+ envstrings 环境变量字串    +--------------------------------+ argv string 命令行字串        +--------------------------------    + env pointers 环境变量指针表+--------------------------------+ argv pointers命令行参数指针表+--------------------------------+ argc 命令行参数个数+--------------------------------    +     main函数的栈帧  +--------------------------------+     被调用函数的栈帧+--------------------------------+         ......                +--------------------------------+       堆(heap)                +--------------------------------+ BSS 未初始化全局数据     +--------------------------------+   Data 初始化的全局数据    +--------------------------------    +   Text 代码段                 +--------------------------------   其中,Heap,BSS,Data这三个段在物理内存中是连续存放的,可以这么理解:这三个是一体的。Text、Stack是独立存放的,这是现在Linux中个段的分布,在0.11中代码段和数据段不是分立的,是在一起的也就是说数据段和代码段是一个段,当然了,堆与BSS也与它们一起了。从0.11的task_struct中还可以看出数据段、堆栈段的描述符是一个,都在ldt[2]处。 堆栈段:  1. 为函数内部的局部变量提供存储空间。  2. 进行函数调用时,存储“过程活动记录”。  3. 用作暂时存储区。如计算一个很长的算术表达式时,可以将部分计算结果压入堆栈。数据段(静态存储区):  包括BSS段的数据段,BSS段存储未初始化的全局变量、静态变量。数据段存储经过初始化的全局和静态变量。代码段:  又称为文本段。存储可执行文件的指令。堆:  就像堆栈段能够根据需要自动增长一样,数据段也有一个对象,用于完成这项工作,这就是堆(heap)。堆区域用来动态分配的存储,也就是用 malloc 函数活的的内存。calloc和realloc和malloc类似。前者返回指针的之前把分配好的内存内容都清空为零。后者改变一个指针所指向的内存块的大小,可以扩大和缩小,他经常把内存拷贝到别的地方然后将新地址返回。   代码段、数据段、堆栈段,这是一个概念堆、栈、全局区、常量区,这是另一个概念 1、栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap):由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。 3、全局区(静态区):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 程序结束后由系统释放。 4、文字常量区:常量字符串就是放在这里的。 程序结束后由系统释放。 5、程序代码区:存放函数体的二进制代码。 在进程被载入内存中时,基本上被分裂成许多小的节(section)。我们比较关注的是6个主要的节:(1) .text 节    .text 节基本上相当于二进制可执行文件的.text部分,它包含了完成程序任务的机器指令。该节标记为只读,如果发生写操作,会造成segmentation fault。在进程最初被加载到内存中开始,该节的大小就被固定。(2).data 节      .data节用来存储初始化过的变量,如:int a =0 ; 该节的大小在运行时固定的。(3).bss 节    栈下节(belowstack section ,即.bss)用来存储为初始化的变量,如:int a; 该节的大小在运行时固定的。(4) 堆节    堆节(heapsection)用来存储动态分配的变量,位置从内存的低地址向高地址增长。内存的分配和释放通过malloc() 和 free() 函数控制。(5) 栈节    栈节(stacksection)用来跟踪函数调用(可能是递归的),在大多数系统上从内存的高地址向低地址增长。同时,栈这种增长方式,导致了缓冲区溢出的可能性。(6)环境/参数节   环境/参数节(environment/argumentssection)用来存储系统环境变量的一份复制文件,进程在运行时可能需要。例如,运行中的进程,可以通过环境变量来访问路径、shell 名称、主机名等信息。该节是可写的,因此在格式串(format string)和缓冲区溢出(buffer overflow)攻击中都可以使用该节。另外,命令行参数也保持在该区域中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值