C语言程序的存储区域_第1页
C语言程序的存储区域_第2页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

个人收集整理-ZQC语言程序的存储区域一、语言程序的存储区域语言编写的程序经过编绎链接后,将形成一个统一的文件,它由几个部分组成,在程序运行时又会产生几个其他部分,各个部分代表了不同的存储区域:代码段( ):代码段由程序中的机器码组成。在语言中,程序语句进行编译后,形成机器代码。在执行程序的过程中,的程序计数器指向代码段的每一条代码,并由处理器依次运行。只读数据段( ):只读数据段是程序使用的一些不会被更改的数据,使用这些数方式类似查表式的操作,由于这些变量不需要更改,因此只需要放置在只读存储器中即可。已初始化读写数据段( ):已初始化数据是在程序中声明,并且具有初值的变量,这些变量需要占用存储器的空间,在程序执行时它们需要位于可读写的内存区域内,并具有初值,以供程序运行时读写。未初始化读写数据段():未初始化读写据是在程序中声明,但是没有初始化的变量,这些变量在程序运行之前不需要占用存储器的空间。堆():堆内存只在程序运行时出现,一般由程序员分配和释放。在具有操作系统的情况下,如果程序员没释放,操作系统可以在程序结束后回收内存。栈():栈内存只在程序运行时出现,在函数内部使用的变量,函数的参数以及返回值将使用栈空间,栈空间由编译器自动分配和释放。语言目标文件的内存布局如下: 代码段,只读数据段,读写数据段,未初始化数据段属于静态区域,而堆和栈属于动态区域。代码段,只读数据段和读写数据段将在连接之后产生,未初始化数据段将在程序初始化的时候开辟,而堆和栈将在程序的运行中分配和释放。语言程序分为映像和运行时两种状态,在编译连接后形成的映像中,将只包含代码段,只读数据段和读写数据段,在程序运行之前,将动态生成未初始化数据段,在程序运行时还将动态形成堆区域和栈区域。一般来说,在静态的映像文件中,各个部分称之为节(),而在运行时的各个部分称之为段(),有时统称为段。二、语言程序的段(静态存储区)、代码段():代码段由各个函数产生,函数的每一个语句将最终经过编绎和汇编生成二进制机器代码(具体生生哪种体系结构的机器代码由编译器决定)。 、只读数据段( ):只读数据段由程序中所使用的数据产生,该部分数据的特点是在运行中不需要改变,因此编译器会将该数据段放入只读的部分中。语言中的只读全局变量,只读局部变量,程序中使用的常量等会在编译时被放入到只读数据区。注意:定义全局变量 ;将生成大小为个字节的只读数据区,并使用初始化。如果定义为: ;则根据字符串长度生成个字节的只读数据段(还有),所以在只读数据段中,一般都需要做完全的初始化。 、读写数据段( ):读写数据段表示了在目标文件中一部分可以读也可以写的数据区,在某些场合它们又被称为已初始化数据段,这部分数据段和代码段,与只读数据段一样都属于程序中的静态区域,但具有可写性的特点。通常已初始化的全局变量和局部静态变量被放在了读写数据段,如:在函数中定义 ;读写数据区的特点是必须在程序经过初始化,如果只定义,没初始值,则不会生成读写数据区,而会定位为未初始化数据区()。如果全局变量(函数外部定义的变量)加入修饰,这表示只能在文件内使用,而不能被其他文件使用。 、未初始化数据段():与读写数据段类似,它也属于静态数据区,但是该段中的数据没有经过初始化。因此它只会在目标文件中被标识,而不会真正称为目标文件中的一段,该段将会在运行时产生。未初始化数据段只在运行的初始化阶段才会产生,因此它的大小不会影响目标文件的大小。语言程序的堆栈(动态存储区)动态存储区都是在程序运行过程中动态分配的,大小在程序运行的过程中动态变化。动态内存管理形式:栈内存从高地址向低地址分配,堆内存将从低地址向高地址分配。动态内存管理实现角度:栈使用线性存储的方式,堆使用链表来实现。栈内存的增长方向是连续的方式,而堆内存的分方式是非连续的方式。从分配与使用上,栈内存与堆内存的区别:栈只有一个入口,就是栈指针,栈指针标识当前栈区域中已经使用与未使用的界限,程序访问栈内存的时候都只能通过栈指针及其偏移量;而堆内存有多个入口,每次分配得到的指针是访问内存的入口,每个分配内存都可被单独释放。在错误处理方面,堆内存在分配的时候,可以在程序中判断()等函数的返回值是否为来确定对内存是否分配成功,是否可以使用。而栈内存在分配的时候,不能在程序中判断其成功与否,当栈内存的使用量比较大的时候(例如使用函数进行递归运算),栈内存可能超出系统的容量,这时程序运行将发生栈溢出错误。在使用的方面,栈内存由编译器管理,不需要程序来管理,同时,函数内部的栈内存是不能被函数的调用者使用的。堆内存需要在程序中处理它的分配与释放情况(由程序调用具体的库函数管理),可以利用灵活的程序将堆内存的指针从函数的内部传递到函数的外部,这时各个函数都可以使用别的函数分配出来的堆内存。在一个函数中使用()等函数分配内存,利用参数和返回值将内存指针传递给其他函数,然后在其他的函数中使用和释放这块内存都是可以的。在语言语法的方面对栈内存和堆内存如何使用没有限制。然而从使用的角度,栈内存更适用于容量较小的变量(例如:语言的基本变量类型、较小的结构体和数组),堆内存则适用于开辟较大块的内存。、栈():栈内存的使用在很大程度上依赖于处理器硬件机制,在处理器中,一般有一个寄存器来表示当前栈指针的位置,通常在内存中分配一块区域,这块内存的上界与下界之间是可用的栈内存区域。栈内存的两种增长方式:一种是向上增长,即从低地址向高址增长,另一种向下增长,即从高地址向低地址增长。注意:栈内存可能使用满栈与空栈两种情况,在满栈的情况下,栈指针当前的位置是已经使用的区域;在空栈的情况下,栈指针当前的位置是没有使用的栈区域。、堆():堆内存的分配(使用函数或)过程中,每次分配将返回一个当前分配地址的指针。在程序中如果多次分配,可得到多个内存指针,每个内存指针都分配内存地址。在释放内存时,对哪个指针操作(使用函数 或),哪个指针所指向的内存就会被释放,而对其它内存区域没有影响。堆内存整体分配方向是逐渐向高地址分配,这只是一个大体的增长方向。在堆内存中,已经使用的区域与未使用的区域是交错的,不像栈区域那样有明显的分界线。三、在语言的程序中,对变量的使用还有以下几点需要注意:函数体中定义的变量通常是在栈上,不需要在程序中进行管理,由编绎器处理。用等分配内存的函数所分配的内存空间在堆上,程序必须保证在使用释放,否则会发生内存泄漏。所有函数体外定义的是全局变量,加了后的变量不管是在函数内部或外部都放在全局区。使用定义的变量将放于程序的只读数据区。一些关于堆栈的问题的回答:使用会在堆栈上分配确切的说是堆()上(当然重载的行为者不一定)而直接声明变量会在栈上分配全局域(如任何函数、类外定义的变量)和静态变量(如有指示符的)分配(确切的说是映射)在静态存储区(大致可以认为和可执行代码运行时内存区域相当),动态分配发生在堆()上(前提是没有重载等分配操作符),局部变量在栈()上分配堆比较小,而栈大这么说有点没谱,大小不是堆和栈的区别,一般而言栈大小确定,栈一旦建立大小就固定了,因此会发生溢出,而堆则可以随时向操作系统申请更多对于一些比较庞大的类对象,一般都要在堆栈上分配由上一点可知,应该是对于一些比较庞大的类对象,一般都要在堆而不是在栈上分配堆栈的性能逊于堆的性能,小对象例如阿什么的都是直接在堆上生成本质上没什么性能差异,最多也就是由于堆上的内存总是只能通过指针和引用来访问,需要多做一次内存寻址而已每个线程有自己的独立的堆和栈。全局变量在公共堆上生成,所以不安全。而对线程独立的堆和栈,都是线程安全,互不相干的。安全不安全全看该对象是否是临界资源(参看操作系统书籍),而不论是在哪里分配的,小明兄的一句话至为妥当:其实不管在还是,说到底也不过是一个普通的内存地址,没特殊的地方,只要是多个不加锁的读写都会引起性能问题,当然小明兄所指性能问题肯定是笔误,我想他指的是安全问题一个有趣的问题: *; 编译通过,运行会出错。因为 静态存储区,是常量区,不可改, 指针在栈区,但是指向的内容是静态存储区的内容,企图通过这个指针改变常量区的内容,所以不对。 ;正确 在静态存储区,在栈区(如果是局部变量的话),赋值给这个变量后,改变,是改变栈区的内容,所以不出错。, 在同一个区,如果是局部变量,就是在栈里面。; 静态存储区,是常量区,不可改四、程序中段的使用下面用一个简单的例子来说明语言中变量和段的对应关系。语言程序中的全局区(静态区),实际对应着下述几个段: ; ; .一般来说,直接定义的全局变量在未初始化数据区,如果该变量有初始化则是在已初始化数据区( ),加上则将放在只读数据区。读写数据段包含了初始化的全局变量 以及局部静态变量 .其差别在于编绎时,是在整个文件中使用(前者)还是在函数内部使用。对于 无论有无 修饰,其都将被放置在读写数据区,只是能否被其它文件引用与否。对于后者就不一样了,它是局部静态变量,放置在读写数据区,如果没修饰,其意义完全改变,它将会是开辟在栈空间的局部变量,而不是静态变量,在这里 后没具体数值,表示静态区大小由后面字符串长度决定。未初始化数据区包含了 与 ,其区别在于前者是全局变量,在所有文件中

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论