「零基础学C语言」知识总结十一:C语言的内存四区

小微 科技「零基础学C语言」知识总结十一:C语言的内存四区已关闭评论132字数 2513阅读模式
摘要一个正在运行着的C编译程序占用的内存分为代码区、静态数据区、未初始化数据区、堆区 和 栈区5个部分。C语言中定义4个内存区间是: 代码区, 静态存储区, 栈区, 堆区. 其中栈区和...

一个正在运行着的C编译程序占用的内存分为代码区、静态数据区、未初始化数据区、堆区 以及 栈区5个部份。

C语言中定义4个内存区间是: 代码区, 静态存储区, 栈区, 堆区. 其中栈区以及堆区是属于动态存储区可执行文件在存储(也就是尚无载入到内存中)的时候,分为:代码区、静态区以及未初始化数据区3个部份。文章源自微观生活(93wg.com)微观生活-https://93wg.com/12220.html

代码区文章源自微观生活(93wg.com)微观生活-https://93wg.com/12220.html

只读区域,程序运行进程中没法做任何修改的存储区域。用于寄存代码以及常量。文章源自微观生活(93wg.com)微观生活-https://93wg.com/12220.html

寄存CPU执行的机器指令。通常,代码区是可同享的(即此外的执行程序可以调用它),由于对于频繁被执行的程序,只需要在内存中有一份代码便可。代码区一般为只读的,使其只读的缘由是避免程序意外埠修改了它的指令。此外,代码区还计划了局部变量的相关信息。文章源自微观生活(93wg.com)微观生活-https://93wg.com/12220.html

代码区 指令依据程序设计流程顺次执行,对于顺序指令,则只会执行一次(每一个过程),如果反复,则需要使用跳转指令,如果进行递归,则需要借助栈来实现。文章源自微观生活(93wg.com)微观生活-https://93wg.com/12220.html

代码段: 代码段一般为指用来寄存程序执行代码的一块内存区域。这部份区域的大小在程序运行前就已经肯定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。文章源自微观生活(93wg.com)微观生活-https://93wg.com/12220.html

在代码段中,也有可能包括一些只读的常数变量,例如字符串常量等文章源自微观生活(93wg.com)微观生活-https://93wg.com/12220.html

。代码区的指令中包含操作码以及要操作的对象(或对象地址引用)。如果是当即数(即具体的数值,如5),将直接包括在代码中;如果是局部数据,将在栈区别配空间,然后引用该数据地址;如果是BSS区以及数据区,在代码中一样将引用该数据地址。此外,代码段还计划了局部数据所申请的内存空间信息。文章源自微观生活(93wg.com)微观生活-https://93wg.com/12220.html

数据区:可读可写区域,程序运行进程中可做任意修改的存储区域。用于寄存变量文章源自微观生活(93wg.com)微观生活-https://93wg.com/12220.html

静态数据区文章源自微观生活(93wg.com)微观生活-https://93wg.com/12220.html

该区包括了在程序中明确被初始化的全局变量、静态变量(包含全局静态变量以及局部静态变量)以及常量数据(如字符串常量),注意 (只初始化一次)。例如,一个不在任何函数内的声明(全局数据):

int max = 99;

使得变量max依据其初始值被存储到初始化数据区中。

static min = 100;

这声明了一个静态数据,如果是在任何函数体外声明,则表示其为一个全局静态变量,如果在函数体内(局部),则表示其为一个局部静态变量。此外,如果在函数名前加之static,则表示此函数只能在当前文件中被调用。

数据段:一般为指用来寄存程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。数据段中的静态数据区寄存的是程序中已初始化的全局变量、静态变量以及常量。

未初始化数据区

未初始化数据区。亦称BSS区,存入的是全局未初始化变量。BSS这个叫法是依据一个初期的汇编运算符而来,这个汇编运算符标志着一个块的开始。BSS区的数据在程序开始执行以前被内核初始化为0或者空指针(NULL)。例如一个不在任何函数内的声明:

long sum[1000];

将变量sum存储到未初始化数据区。

BSS 段:一般为指用来寄存程序中未初始化的全局变量的一块内存区域。BSS 是英文Block Started by Symbol 的简称。BSS 段属于静态内存分配,即程序一开始就将其清零了。一般在初始化时BSS段部份将会清零。

栈区

栈区(stack)。由编译器自动分配释放内存的区间,所得的内存空间一般都是连续的,是用来寄存函数的参数值、局部变量的值等。寄存函数的参数值、局部变量的值,和在进行任务切换时寄存当前任务的上下文内容。其操作方式相似于数据结构中的栈。每一当一个函数被调用,该函数返回地址以及一些关于调用的信息,比如某些存放器的内容,被存储到栈区。然后这个被调用的函数再为它的自动变量以及临时变量在栈区上分配空间,这就是C实现函数递归调用的办法。

每一执行一次递归函数调用,一个新的栈框架就会被使用,这样这个新实例栈里的变量就不会以及该函数的另外一个实例栈里面的变量搅浑。

​栈(stack):栈又称堆栈, 是用户寄存程序临时创立的局部变量,也就是说咱们函数括弧&

除了此之外,在函数被调历时,其参数也会被压入发起调用的过程栈中,并且待到调用收场后,函数的返回值也会被寄存回栈中。因为栈的先进先出特色,所以栈尤其利便用来保留/ 恢复调用现场。从这个意义上讲,咱们可以把堆栈看成一个存放、交流临时数据的内存区。

堆区

堆区(heap)。用于动态内存分配。堆在内存中位于bss区以及栈区之间。一般由程序员分配以及释放,若程序员不释放,程序收场时有可能由OS回收。堆中的内存区域不是连续的,还是将有效的内存区域经由链表指针连接起来的​。

堆(heap): 用于寄存过程运行中被动态分配的内存段,它的大小其实不固定,可动态扩张或缩减。当过程调用malloc 等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当应用free 等函数释放内存时,被释放的内存从堆中被剔除了(堆被缩减)。

在将利用程序加载到内存空间执行时,操作系统负责代码段、数据段以及BSS段的加载,并将在内存中为这些段分配空间。栈段亦由操作系统分配以及管理,而不需要程序员显示地管理;堆段由程序员自己管理,即显式地申请以及释放空间。

此外,可执行程序在运行时拥有相应的程序属性。在有操作系统支撑时,这些属性页由操作系统管理以及保护。

C语言程序编译完成以后,已初始化的全局变量保留在数据段中,未初始化的全局变量保留在BSS段中。数据段以及代码段都在可执行文件中,由系统从可执行文件中加载;而BSS段不在可执行文件中,由系统初始化。BSS段只保留没有值的变量,所以事实上它其实不需要保留这些变量的映像。运行时所需要的BSS段大小记录在目标文件中,然而BSS段其实不盘踞目标文件的任何空间。

堆区与栈区的差异:

在栈上所申请的内存空间是系统自动分配的,所以当咱们出了变量所在的作用域后,系统会自动咱们回收这些空间,而在堆上申请的空间是要咱们自己手动操作的,当出了相应的作用域之后,咱们需要调用free或者delete来释放所申请的内存空间,如果咱们不及时得对这些空间进行释放,那么内存中的内存碎片就愈来愈多,从而咱们的实际内存空间也就会变的越 来越少,即,孤立的内存块愈来愈多。

以上就是微观生活(93wg.com)关于“「零基础学C语言」知识总结十一:C语言的内存四区”的详细内容,希望对大家有所帮助!

继续阅读
 
小微
  • 版权声明: 本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们(管理员邮箱:81118366@qq.com),情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!
  • 转载请务必保留本文链接:https://93wg.com/12220.html