㈠ 内存的分配方式有哪几种
内存的三种分配方式:
1. 从静态存储区分配:此时的内存在程序编译的时候已经分配好,并且在程序的整个运行期间都存在。全局变量,static变量等在此存储。
2. 在栈区分配:相关代码执行时创建,执行结束时被自动释放。局部变量在此存储。栈内存分配运算内置于处理器的指令集中,效率高,但容量有限。
3. 在堆区分配:动态分配内存。用new/malloc时开辟,delete/free时释放。生存期由用户指定,灵活。但有内存泄露等问题。
常见内存错误及对策
1. 内存分配未成功,却被使用。
对策:使用内存之前检查是否分配成功。用p!=NULL判断。
2. 内存分配成功,未初始化就被使用。
内存的缺省值没有统一的标准。大部分编译器以0作为初始值,但不完全是。
对策:内存初始化时赋初值。
3. 内存操作越界。
对策:只能是小心了。
4. 释放了内存,仍然使用。
(1) 使用显示delete和free的野指针。
对策:释放完内存,将指针置为NULL。
(2) 使用隐式delete和free的野指针。主要是指函数返回指向栈内存的指针或引用。
对策:当然是不要返回就可以了。
5. 未释放内存,导致内存泄露。
用new/malloc开辟了内存,没用delete/free释放.
对策:new和delete的个数一定相同;malloc和free的个数一定相同;new[]和[]delete一定对应。
㈡ 内存的连续分配有哪些方式,各有什么特点
内存的连续分配方式有:单一连续分配、固定分区分配、动态分区分配以及动态重定位分区分配四种方式。
单一连续分配:只能用于单用户、单任务的操作系统中。
固定分区分配:可运行多道程序的存储管理方式答绝。
动态分区分配:根据戚举蠢进程的实际需要,动态地为之分配内存空间。
可重定位分区分配:必须把一高陪个系统或用户程序装入一连续的内存空间。
㈢ c语言内存有几种分配方式
基本上C程序的元素存储在内存的时候有3种分配策略:
静态分配
如果一个变量声明为全局变量或者是函数的静态变量,这个变量的存储将使用静态分配方式。静态分配的内存一般会被编译器放在数据段或代码段来存储,具体取决于实现。这样做的前提是,在编译时就必须确定变量的大小。 以IA32的x86平台及gcc编译器为例,全局及静态变量放在数据段的低端;全局及静态常量放在代码段的高端
自动分配
函数的自动局部变量应该随着函数的返回会自动释放(失效),这个要求在一般的体系中都是利用栈(Stack)来满足的。相比于静态分配,这时候,就不必绝对要求这个变量在编译时就必须确定变量的大小,运行时才决定也不迟,但是C89仍然要求在编译时就要确定,而C99放松了这个限制。但无论是C89还是C99,都不允许一个已经分配的自动变量运行时改变大小。
所以说C函数永远不应该返回一个局部变量的地址。
要指出的是,自动分配也属于动态分配,甚至可以用alloca函数来像分配堆(Heap)一样进行分配,而且释放是自动的。
动态分配
还有一种更加特殊的情况,变量的大小在运行时有可能改变,或者虽然单个变量大小不变,变量的数目却有很大弹性,不能静态分配或者自动分配,这时候可以使用堆(Heap)来满足要求。ANSI C定义的堆操作函数是malloc、calloc、realloc和free。
使用堆(Heap)内存将带来额外的开销和风险。
㈣ 分区存储管理中常用哪些分配策略
1、固定分区存储管理
其基本思想是将内存划分成若干固定大小的分区,每个分区中最多只能装入一个作业。当作业申请内存时,系统按一定的算法为其选择一个适当的分区,并装入内存运行。由于分区大小是事先固定的,因而可容纳作业的大小受到限制,而且当用户作业的地址空间小于分区的存储空间时,造成存储空间浪费。
一、空间的分配与回收
系统设置一张“分区分配表”来描述各分区的使用情况,登记的内容应包括:分区号、起始地址、长度和占用标志。其中占用标志为“0”时,表示目前该分区空闲;否则登记占用作业名(或作业号)。有了“分区分配表”,空间分配与回收工作是比较简单的。
二、地址转换和存储保护
固定分区管理可以采用静态重定位方式进行地址映射。
为了实现存储保护,处理器设置了一对“下限寄存器”和“上限寄存器”。当一个已经被装入主存储器的作业能够得到处理器运行时,进程调度应记录当前运行作业所在的分区号,且把该分区的下限地址和上限地址分别送入下限寄存器和上限寄存器中。处理器执行该作业的指令时必须核对其要访问的绝对地址是否越界。
三、多作业队列的固定分区管理
为避免小作业被分配到大的分区中造成空间的浪费,可采用多作业队列的方法。即系统按分区数设置多个作业队列,将作业按其大小排到不同的队列中,一个队列对应某一个分区,以提高内存利用率。
2、可变分区存储管理
可变分区存储管理不是预先将内存划分分区,而是在作业装入内存时建立分区,使分区的大小正好与作业要求的存储空间相等。这种处理方式使内存分配有较大的灵活性,也提高了内存利用率。但是随着对内存不断地分配、释放操作会引起存储碎片的产生。
一、空间的分配与回收
采用可变分区存储管理,系统中的分区个数与分区的大小都在不断地变化,系统利用“空闲区表”来管理内存中的空闲分区,其中登记空闲区的起始地址、长度和状态。当有作业要进入内存时,在“空闲区表”中查找状态为“未分配”且长度大于或等于作业的空闲分区分配给作业,并做适当调整;当一个作业运行完成时,应将该作业占用的空间作为空闲区归还给系统。
可以采用首先适应算法、最佳(优)适应算法和最坏适应算法三种分配策略之一进行内存分配。
二、地址转换和存储保护
可变分区存储管理一般采用动态重定位的方式,为实现地址重定位和存储保护,系统设置相应的硬件:基址/限长寄存器(或上界/下界寄存器)、加法器、比较线路等。
基址寄存器用来存放程序在内存的起始地址,限长寄存器用来存放程序的长度。处理机在执行时,用程序中的相对地址加上基址寄存器中的基地址,形成一个绝对地址,并将相对地址与限长寄存器进行计算比较,检查是否发生地址越界。
三、存储碎片与程序的移动
所谓碎片是指内存中出现的一些零散的小空闲区域。由于碎片都很小,无法再利用。如果内存中碎片很多,将会造成严重的存储资源浪费。解决碎片的方法是移动所有的占用区域,使所有的空闲区合并成一片连续区域,这一技术称为移动技术(紧凑技术)。移动技术除了可解决碎片问题还使内存中的作业进行扩充。显然,移动带来系统开销加大,并且当一个作业如果正与外设进行I/O时,该作业是无法移动的。
3、页式存储管理
基本原理
1.等分内存
页式存储管理将内存空间划分成等长的若干区域,每个区域的大小一般取2的整数幂,称为一个物理页面有时称为块。内存的所有物理页面从0开始编号,称作物理页号。
2.逻辑地址
系统将程序的逻辑空间按照同样大小也划分成若干页面,称为逻辑页面也称为页。程序的各个逻辑页面从0开始依次编号,称作逻辑页号或相对页号。每个页面内从0开始编址,称为页内地址。程序中的逻辑地址由两部分组成:
逻辑地址
页号p
页内地址 d
3.内存分配
系统可用一张“位示图”来登记内存中各块的分配情况,存储分配时以页面(块)为单位,并按程序的页数多少进行分配。相邻的页面在内存中不一定相邻,即分配给程序的内存块之间不一定连续。
对程序地址空间的分页是系统自动进行的,即对用户是透明的。由于页面尺寸为2的整数次幂,故相对地址中的高位部分即为页号,低位部分为页内地址。
3.5.2实现原理
1.页表
系统为每个进程建立一张页表,用于记录进程逻辑页面与内存物理页面之间的对应关系。地址空间有多少页,该页表里就登记多少行,且按逻辑页的顺序排列,形如:
逻辑页号
主存块号
0
B0
1
B1
2
B2
3
B3
2.地址映射过程
页式存储管理采用动态重定位,即在程序的执行过程中完成地址转换。处理器每执行一条指令,就将指令中的逻辑地址(p,d)取来从中得到逻辑页号(p),硬件机构按此页号查页表,得到内存的块号B’,便形成绝对地址(B’,d),处理器即按此地址访问主存。
3.页面的共享与保护
当多个不同进程中需要有相同页面信息时,可以在主存中只保留一个副本,只要让这些进程各自的有关项中指向内存同一块号即可。同时在页表中设置相应的“存取权限”,对不同进程的访问权限进行各种必要的限制。
4、段式存储管理
基本原理
1.逻辑地址空间
程序按逻辑上有完整意义的段来划分,称为逻辑段。例如主程序、子程序、数据等都可各成一段。将一个程序的所有逻辑段从0开始编号,称为段号。每一个逻辑段都是从0开始编址,称为段内地址。
2.逻辑地址
程序中的逻辑地址由段号和段内地址(s,d)两部分组成。
3.内存分配
系统不进行预先划分,而是以段为单位进行内存分配,为每一个逻辑段分配一个连续的内存区(物理段)。逻辑上连续的段在内存不一定连续存放。
3.6.2实现方法
1.段表
系统为每个进程建立一张段表,用于记录进程的逻辑段与内存物理段之间的对应关系,至少应包括逻辑段号、物理段首地址和该段长度三项内容。
2.建立空闲区表
系统中设立一张内存空闲区表,记录内存中空闲区域情况,用于段的分配和回收内存。
3.地址映射过程
段式存储管理采用动态重定位,处理器每执行一条指令,就将指令中的逻辑地址(s,d)取来从中得到逻辑段号(s),硬件机构按此段号查段表,得到该段在内存的首地址S’, 该段在内存的首地址S’加上段内地址d,便形成绝对地址(S’+d),处理器即按此地址访问主存。
5、段页式存储管理
页式存储管理的特征是等分内存,解决了碎片问题;段式存储管理的特征是逻辑分段,便于实现共享。为了保持页式和段式上的优点,结合两种存储管理方案,形成了段页式存储管理。
段页式存储管理的基本思想是:把内存划分为大小相等的页面;将程序按其逻辑关系划分为若干段;再按照页面的大小,把每一段划分成若干页面。程序的逻辑地址由三部分组成,形式如下:
逻辑地址
段号s
页号p
页内地址d
内存是以页为基本单位分配给每个程序的,在逻辑上相邻的页面内存不一定相邻。
系统为每个进程建立一张段表,为进程的每一段各建立一张页表。地址转换过程,要经过查段表、页表后才能得到最终的物理地址。
㈤ 动态储存分配的特点和优化目标有哪些
动态存储分配即指在目标程序或操作系统运行阶段动态地为源程序中的量分配存储空间。根据查询相关公开信息显示,动态存储分配包括栈式或堆两种分配方式。采用动态存储分配进行处理的量滑乱,并非运派所有的工作全部放在运行时刻做,编译程序信悄档在编译阶段要为其设计好运行阶段存储组织形式,并为每一个数据项安排好它在数据区中的相对位置。
㈥ 存储空间的分配技术有哪些
存储空间的分配技术可以分为以下几种:
静态分配:静态分配是指在计算机系统中为程序或数据分配一定的存储空间,分配的空间在程序执行期间不变。静态分配的优点是简单、快速,但缺点是空间利用率低,容易余兄出现空间浪费或不足的情况。
动态分配:动态分配是指在程序运行期间根据需要动态地为程序或数据分配存储空间。动态分配的优点是可以充分利用存储空间,避免空间浪费或不足的情况,但缺点是分配和释放空间的过程比较复杂,容易出现内存泄漏或空间碎片等问题。
分页式分配:分页式分配是指将存储空间划分为固定大小的页面,并将程序宽仔或数据按照页面进行分配。这种技术可以充分利用存储空间,避免空间浪费,也可以避免空间碎片的问题,但需要花费一定的开销来维护页面表等数据结构。
段式分配:段式分配是指将存储空间按照逻辑上的段进行划分,并为程序或数据分配不同大小的段空间。这种技术可以更好地满足不同程序或数据的存储需求,但需要考虑内存碎片和段的大小等问题。
段页式分配:段页式分配是指将存储空间先按照段进行划分,再将每个段划分为固定大小的页面,并将程序或数据按照段和页面进行分配。这种技术可以更好地结合段式和分页式分配的优点,但需要处理复杂的地址映射和内存管理问题慎毁汪。
不同的存储空间分配技术适用于不同的计算机应用和场景,需要根据具体的需求和实际情况进行选择和优化。
㈦ 运行时环境中存储分配策略包括
程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的.
静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间.这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求.
栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存.和我们在数据结构所熟知的栈一样,栈式存储分配按照先进后出的原则进行分配。
静态存储分配要求在编译时能知道所有变量的存储要求,栈式存储分配要求在过程的入口处必须知道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例.堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放.
㈧ 存储器管理的连续分配存储管理方式有哪些
连续分配方式.它是指为了一个用户程序分配一个连续的内存空间.可以分为单一连续分配、固定分区分配、动态分区分配以及动态重定位分区分配四种方式。不过今天我们讲的是固定分区分配和动态分区分配。
固定分区分配是最简单的一种可运行多道程序的存储管理方式。 一、基本思想:在系统中把用户区预先划分成若干个固定分区(每个分区首地址固定,每个分区长度是固定),每个分区可供一个用户程序独占使用。注意:每个分区大小可以相同,也可以不相同。 二、主存分配与回收:借助主存分配表。 三、地址转换(静态重定位):物理地址=分区起始地址+逻辑地址。其中划分分区方法包括分区大小相等和分区大小不等。
动态分区分配是根据进程的实际需要,动态地为之分配内存空间。一、基本思想:按用户程序需求动态划分主存供用户程序使用。(每个分区首地址是动态的,每个分区的长度也是动态的) 二、主存分配与回收-->(1)未分配表(登记未分配出去的分区情况);(2)已分配表(登记已经分配出去的分区情况)。 三、地址转换:物理地址=分区起始地址+逻辑地址。 四、分区分配算法:从空闲分区中选择分区分www.hbbz08.com 配给用户程序的策略。 (1)首次适应算法(最先适应)顺序查询为分配表,从表中找出第一个可以满足作业申请的分区划分部分分配给用户作业。 (2)循环首次适应算法 (3)最佳适应算法:从空闲分区中找出一个能满足用户作业申请的最小空闲分区划分给用户作业使用(有利于大作业执行) (4)最坏适应算法:从空闲分区中挑最大的分区划分给用户程序使用(有利于中、小作业执行)
㈨ 常见的存储分配策略有几种它们都适合于什么性质的语言
1 静态分配若在编译阶段就能确定源程序中各个数据实体的存储空间大小,则可以采用较简单的静态存储管理。适合静态管理的语言应具备条件:数组上下界是常数、过程调用不允许递归、不允许动态建立数据实体。
2栈式分配适用于允许递归调用的程序设计语言
3 堆式分配对于允许程序在运行时为变量动态申请和释放存储空间的语言,采用堆式分配是最有效的解决方案
㈩ 编译原理中常见的存储分配策略有哪些
静态存储分配策略和动态存储分配策略,动态存储分配时可采用栈式动态存储分配和堆式动态存储分配