【C 数据结构-动态内存管理】4. 无用单元收集(垃圾回收机制)

news2024/10/6 1:38:53

文章目录

  • 【 1. 问题描述与解决方法 】
  • 【 2. 中断回收机制 】

【 1. 问题描述与解决方法 】

  • 问题描述
    动态存储管理的运行机制可以概括为:当用户发出申请空间的请求后,系统向用户分配内存;用户运行结束释放存储空间后,系统回收内存。这两部操作都是在用户给出明确的指令后,系统对存储空间进行有效地分配和回收。但是在实际使用过程中,有时会因为用户申请了空间,但是 内存在使用完成后没有向系统发出释放的指令,导致存储空间既没有被使用也没有被回收,变为了无用单元或者会产生悬挂访问的问题
    • 无用单元 是一块用户不再使用,但是系统无法回收的存储空间。
      例如,在C语言中,用户可以通过 malloc 和 free 两个功能函数来动态申请和释放存储空间,当用户使用 malloc 申请的空间使用完成后,没有使用 free 函数进行释放,那么该空间就会成为无用单元。

    • 悬挂访问 :假设使用 malloc 申请了一块存储空间,有 多个指针同时指向这块空间,当其中一个指针完成使命后,私自将该存储空间使用 free 释放掉,导致 其他指针处于悬空状态,如果 释放掉的空间被再分配后,再通过之前的指针访问,就会造成错误,数据结构中称这种访问为悬挂访问。

  • 解决方法
    解决存储空间可能成为无用单元或者产生悬挂访问的方法有两个:
    1. 每个申请的存储空间设置一个计数域,这个计数域 记录的是 指向该存储空间的指针数目,只有当计数域的值为 0 时,该存储空间才会被释放
    2. 中断回收机制,即在程序运行时, 所有的存储空间无论是处于使用还是空闲的状态,一律不回收,当系统中的 可利用空间表为空时,将程序 中断,对当前 不再使用状态的存储空间一律回收,全部链接成一个新的可利用空间表后,程序继续执行。下面将详细介绍第二种方法。
  • PS:实际上,无用单元收集本身都是很 费时间 的,所以 无用单元的收集不适用于实时处理的情况中使用

【 2. 中断回收机制 】

  • 如果想使用上面的第二种解决方法,可以分为两步进行:
    1. 对所有当前正在使用的 存储空间加上被占用的标记(对于广义表来说,可以在每个结点结构的基础上,添加一个 mark 的标志域。)在初始状态下,所有的存储空间全部标志为 0表示未被占用,被占用时程序标记为 1
    2. 依次遍历所有的存储空间,将所有标记为 0 的存储空间链接成一个新的可利用空间表。
  • 对正在被占用的存储空间进行标记的方法有以下三种:
    • 从当前正在工作的指针变量开始,采用 递归 算法依次将所有表中的存储结点中的标志域全部设置为 1;
    • 第一种方法中使用递归算法实现的遍历。而递归底层使用的栈的存储结构,所以也可以直接使用 的方式进行遍历;
    • 以上两种方法都是使用栈结构来记录遍历时指针所走的路径,便于在后期可以沿原路返回。所以第三种方式就是使用 其他的方法代替栈的作用
  • 对被占用的存储空间进行标记的第三种实现方法:
    添加三个指针,p 指针指向当前遍历的结点,t 指针永远指向 p 的父结点,q 指向 p 结点的表头或者表尾结点。在遍历过程遵循以下原则:
    • 当 q 指针指向 p 的表头结点时,可能出现 3 种情况:
      • p 结点的表头结点只是一个元素结点,没有表头或者表尾,这时只需要对该表头结点打上标记后令 q 指向 p 的表尾;
      • p 结点的表头结点是空表或者是已经做过标记的子表,这时直接令 q 指针指向 p 结点的表尾即可;
      • p 结点的表头是未添加标记的子表,这时就需要遍历子表,令 p 指向 q,q 指向 q 的表头结点。同时 t 指针相应地往下移动,但是在移动之前需要记录 t 指针的移动轨迹。记录的方法就是令 p 结点的 hp 域指向 t,同时设置 tag 值为 0。
    • 当 q 指针指向 p 的表尾结点时,可能出现 2 种情况:
      • p 指针的表尾是未加标记的子表,就需要遍历该子表,和之前的类似,令 p 指针和 t 指针做相应的移动,在移动之前记录 t 指针的移动路径,方法是:用 p 结点的 tp 域指向 t 结点,然后在 t 指向 p,p 指向 q。
      • p 指针的表尾如果是空表或者已经做过标记的结点,这时 p 结点和 t 结点都回退到上一个位置。
        由于 t 结点的回退路径分别记录在结点的 hp 域或者 tp 域中,在回退时需要根据 tag 的值来判断:如果 tag 值为 0 ,t 结点通过指向自身 hp 域的结点进行回退;反之,t 结点通过指向其 tp 域的结点进行回退。
  • 例如,下图为一个待遍历的广义表:
    在这里插入图片描述
  • 该广义表每个结点的结构如下图所示:
    在这里插入图片描述
  • 在遍历广义表时,从广义表的 a 结点开始,则 p 指针指向结点 a,同时 a 结点中 mark 域设置为 1,表示已经遍历过,t 指针为 nil,q 指针指向 a 结点的表头结点,初始状态如下图所示:
    在这里插入图片描述
  • 由于 q 指针指向的结点 b 的 tag 值为 1,表示该结点为表结构,所以此时 p 指向 q,q 指向结点 c,同时 t 指针下移,在 t 指针指向结点 a 之前,a 结点中的 hp 域指向 t,同时 a 结点中 tag 值设为 0。效果如下图所示:
    在这里插入图片描述
  • 通过 q 指针指向的结点 c 的 tag=1,判断该结点为表结点,同样 p 指针指向 c,q 指针指向 d,同时 t 指针继续下移,在 t 指针指向 结点 b 之前,b 结点的 tag 值更改为 0,同时 hp 域指向结点 a,效果图如下图所示:
    在这里插入图片描述
  • 通过 q 指针指向的结点 d 的 tag=0,所以,该结点为原子结点,此时根据遵循的原则,只需要将 q 指针指向的结点 d 的 mark 域标记为 1,然后让 q 指针直接指向 p 指针指向结点的表尾结点,效果图如下图所示:
    在这里插入图片描述
  • 当 q 指针指向 p 指针的表尾结点时,同时 q 指针为空,这种情况的下一步操作为 p 指针和 t 指针全部上移动,即 p 指针指向结点 b,同时 t 指针根据 b 结点的 hp 域回退到结点 a。同时由于结点 b 的tag 值为 0,证明之前遍历的是表头,所以还需要遍历 b 结点的表尾结点,同时将结点 b 的 tag 值改为 1。效果图如下图所示:
    在这里插入图片描述
  • 由于 q 指针指向的 e 结点为表结点,根据 q 指针指向的 e 结点是 p 指针指向的 b 结点的表尾结点,所以所做的操作为:p 指针和 t 指针在下移之前,令 p 指针指向的结点 b 的 tp 域指向结点 a,然后给 t 赋值 p,p 赋值 q。q 指向 q 的表头结点 f。效果如下图所示:
    在这里插入图片描述
  • 由于 q 指针指向的结点 f 为原子结点,所以直接 q 指针的 mark 域设为 1 后,直接令 q 指针指向 p 指针指向的 e 结点的表尾结点。效果如下图所示:
    在这里插入图片描述
  • 由于 p 指针指向的 e 结点的表尾结点为空,所以 p 指针和 t 指针都回退。由于 p 指针指向的结点 b 的 tag 值为 1,表明表尾已经遍历完成,所以 t 指针和 p 指针继续上移,最终遍历完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1649510.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5月5日智渍洁对江苏某公司冷却塔清洗-智渍洁

简报:5月5日智渍洁对江苏某公司冷却塔清洗 5月5日智渍洁对江苏某公司冷却塔清洗 - 重庆智渍洁环保科技有限公司简报:5月5日智渍洁对江苏某公司冷却塔清洗https://www.zhizijie.com/hl/zixun/gongsi/236.html

Python Dash库:一个Web应用只需几行代码

大家好,在数据科学领域,数据可视化是将数据以图形化形式展示出来,帮助我们更直观地理解数据。Python中有一个非常流行的数据可视化库叫做Dash,Dash以其简洁、高效和强大的功能而闻名,它允许开发者快速构建交互式Web应用…

Vulnhub项目:NAPPING: 1.0.1

1、靶机介绍 靶机地址:Napping: 1.0.1 ~ VulnHub 2、渗透过程 老规矩,先探测,靶机ip:192.168.56.152 本机ip:192.168.56.146 来看一看靶机开放哪些端口,nmap一下 nmap -sS -sV -A -T5 192.168.56.152 开…

Zookeeper服务

一、什么是Zookeeper Zookeeper 是一个分布式应用程序的协调服务,它提供了一个高性能的分布式配置管理、分布式锁服务和分布式协调服务。它是 Apache 软件基金会的一个项目,被设计用来处理大规模的分布式系统中的一些关键问题。 Zookeeper的组成员关系&…

java10基础(this super关键字 重写 final关键字 多态 抽象类)

目录 一. this和super关键字 1. this关键字 2. super关键字 二. 重写 三. final关键字 四. 多态 五. 抽象类 1. 抽象方法 2. 抽象类 3. 面向抽象设计 一. this和super关键字 1. this关键字 this 当前对象的引用 this.属性 this.方法名() this() -- 调用构造函数 …

2024 AI中转计费平台系统源码

简介: 2024 AI中转计费平台系统源码 文件下载https://www.skpan.cn/CNZjzyC4txX 图片:

荷香堪筑梦,鸳鸯和月寻。(变相BFS搜索)

本题链接:登录—专业IT笔试面试备考平台_牛客网 题目: 样例: 输入 3 4 2 .... ***. ..a. 输出 yes 思路: 根据题意,这里 1 s 可以移动多次,我们将每次可以移动避开雪的的位置存储起来,判断当…

运维开发工程师教程之MongoDB单机版设置

MongoDB单机版设置 一、创建虚拟机 在VMware Workstation软件中新建一个虚拟机,具体操作步骤如下: ①运行VMware Workstation软件,进入到主界面,单击“创建新的虚拟机”来创建新的虚拟机,如图3-1所示。 图3-1 VMware…

3D相机及应用

无论是2D相机和3D相机,在工业应用中都有着不可或缺的作用。3D相机与2D相机的最大区别在于,3D相机可以获取真实世界尺度下的3D信息,而2D相机只能获取像素尺度下的2D平面图像信息。通过3D相机得到的数据,我们可以还原出被测量物体的…

shell脚本脚本变量

shell脚本的概念: 1.讲要执行的命令按顺序保存到一个文本文件 2.给文件可执行权限 3.可以结合各种shell控制语句以完成更复杂的操作 linux中包含shell的文件有 [rootlocalhost ~]# cat /etc/shells /bin/sh #UNIX最初使用的 shell,已经被…

流量暴涨!抖音+快手+小红书获客攻略!

在数字营销的海洋中,抖音、快手和小红书无疑是三座巨大的灯塔,照亮了品牌和个人获取流量的道路。这些平台不仅拥有庞大的用户基础,而且其独特的算法和社交特性让获客变得更加高效而精准。接下来,让我们深入探讨如何通过这三个平台…

鸿蒙OpenHarmony【基于Hi3516DV300开发板(时钟应用开发)】

概述 本文将介绍如何快速搭建基于OpenHarmony标准系统(Hi3516DV300开发板)的应用开发环境,并基于一个时钟APP示例逐步展示应用的创建、开发、调试和安装等流程。示例代码可以通过本链接获取。 时钟App是一款显示实时时间的应用,…

WouoUIPagePC端实现

WouoUIPagePC端实现 WouoUIPage是一个与硬件平台无关,纯C语言的UI库(目前只能应用于128*64的单色OLED屏幕上,后期会改进,支持更多尺寸)。因此,我们可以在PC上实现它,本文就以在PC上使用 VScode…

124.反转链表(力扣)

题目描述 代码解决(思路1:双指针) class Solution { public:ListNode* reverseList(ListNode* head) {ListNode*temp;//保存cur下一个节点ListNode*curhead;ListNode*preNULL;while(cur){tempcur->next;// 保存一下 cur的下一个节点&#…

新的循环体和define

目录 do while讲解 练习: 结果: 分析: 定义:宏(define) 练习: 结果: 分析: define的优缺点 优点: 缺点: 作业: 大家假期…

Git命令Gitee注册idea操作git超详细

文章目录 概述相关概念下载和安装常见命令远程仓库介绍与码云注册创建介绍码云注册远程仓库操作关联拉取推送克隆 在idea中使用git集成add和commit差异化比较&查看提交记录版本回退及撤销与远程仓库关联 push从远程仓库上拉取,克隆项目到本地创建分支切换分支将…

使用wxPython和pandas模块生成Excel文件

介绍: 在Python编程中,有时我们需要根据特定的数据生成Excel文件。本文将介绍如何使用wxPython和pandas模块来实现这个目标。我们将创建一个简单的GUI应用程序,允许用户选择输出文件夹和输入的Excel文件,并根据Excel文件中每个单…

代码随想录算法训练营第十八天:二叉树的层序遍历(中间放假)

代码随想录算法训练营第十八天:二叉树的层序遍历(中间放假) ‍ ​​ 102.二叉树的层序遍历 力扣题目链接(opens new window) 给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右…

算法提高之能量项链

算法提高之能量项链 核心思想&#xff1a;区间dp 通过观察发现可以将n个珠子最后的n1个数看作石子 合并石子 在l~r的范围内 找k作隔断 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 110,M N<<…

【PCB字符批量修改】- PCB板工艺及AD软件配置

软件版本 选择丝印-单机右键&#xff0c;选择find similar objects 第二步单机Apply 第三步选择OK 第四步在Panels中选择Properties里面修改Text Height和Stroke Width 到此搞定&#xff01;