当前位置:   article > 正文

操作系统原理与实验——实验十分离散存储管理方式的模拟和实现(分段式)_希冀段式存储管理模拟实验

希冀段式存储管理模拟实验

实验指南

运行环境:

Dev c++

算法思想:

本实验是模拟分段存储管理,系统需要建立两张分区表,分别是已分配和未分配分区表,首先根据装入作业的大小判断是否小于空闲分区的总容量,若满足,则对该作业继续进行分段,每输入一个分段大小就在空闲分区中找到第一个没有使用且足够大的分区,若找到将该分区标记为该作业名和对应的分段号,修改已分配和未分配分区表,并打印内存分配信息。对已分配分区的回收,首先输入要回收的作业名,找到该作业的每一段所在的分区,修改已分配分区表,未分配分区表(根据是否存在上下邻),打印回收成功后内存分配信息。

关键数据结构定义:

//内存结构体

typedef struct memory_node

{

    int size; //内存大小

    int address; //内存始址

} memoryNode;

memoryNode memory;

//分区结构体

typedef struct link_node

{

    int id;//分区号

    int size; //分区长度

    int address; //分区始址

    char flag[20]; //分区状态,空闲或者占用作业名

    struct link_node* next;

} node;

//段表

typedef struct segment_node

{

    int a[10][10];

    struct segment_node *next;

} segmentNode;

程序框架:

//函数名 :initMemory  参数:无

node* initMemory()

{

  //函数功能:初始化内存空间

}

//函数名:operation 参数:node* head

int operation(node *head)

{

//函数功能:打印操作菜单,选择需要进行的操作,输入1进行内存 分配,输入2进  行内存去配,输入0退出

}

//函数名:allocate 参数:node* head

void allocate(node *head)

{

//函数名:输入作业名和大小,默认采用最先分配

}

//函数名:firstAllocation 参数:node* head,int size,charc[10]

void firstAllocation(node* head,int size,char c[10])

{

 //函数功能:对作业进行分段,并采用最先分配,分段结束后打印 段表

}

        //函数名:reorder 参数:node* head

void reorder(node* head)

{

   //函数功能:对分区和未分区的存储区域进行编号 

}

//函数名:recycle 参数:node* head

void recyle(node* head) //回收算法

{

   //函数功能:对归还分区按情况进行处理,,有上邻有下邻,有上邻     无下邻,无上邻有下邻,无上邻无下邻

            

}

//函数名:print参数:node* head

void print(node* head)

{

   //函数功能:打印主存分配表

}

int main()

{

    node* head;

    head=initMemory();

    while(1)

    {

        int c;

        c=operation(head);

        if(c==1)

        {

            break;

        }

    }

    return 0;

}

测试用例:

/*

256

40

1

jobA

50

2

20

30

1

jobB

100

3

30

35

35

2

jobB

2

jobA

0

*/

关键代码

  1. #include<stdio.h>
  2. #include<malloc.h>
  3. #include<string.h>
  4. int g_size;
  5. //内存结构体
  6. typedef struct memory_node
  7. {
  8. int size; //内存大小
  9. int address; //内存始址
  10. } memoryNode;
  11. memoryNode memory;
  12. //分区结构体
  13. typedef struct link_node
  14. {
  15. int id;//分区号
  16. int size; //分区长度
  17. int address; //分区始址
  18. char flag[20]; //分区状态,空闲或者占用作业名
  19. struct link_node* next;
  20. } node;
  21. //段表
  22. typedef struct segment_node
  23. {
  24. int sum;
  25. char jobname[20];
  26. int a[10][10];
  27. struct segment_node *next;
  28. } segmentNode;
  29. node* initMemory();
  30. node* operation(node *head);
  31. node* allocate(node *head);
  32. node* firstAllocation(node* head,int size,char c[10]);
  33. node* reorder(node* head);
  34. node* recyle(node* head);
  35. void print(node* head);
  36. node *distribute = NULL;
  37. segmentNode *duanbiao =NULL;
  38. //函数名 :initMemory 参数:无
  39. node* initMemory()
  40. {
  41. //函数功能:初始化内存空间
  42. printf("请输入内存大小:");
  43. scanf("%d",&memory.size);g_size = memory.size;
  44. printf("请输入起始地址:");
  45. scanf("%d",&memory.address);
  46. node* p = (node *) malloc ( sizeof(node) * memory.size ); //分配可以放得下265个node的内存空间
  47. p->next = NULL;
  48. p->id = 1;
  49. p->size = memory.size;
  50. p->address = memory.address;
  51. p->flag[0] = '\0';
  52. return p;
  53. }
  54. //函数名:operation 参数:node* head
  55. node* operation(node *head)
  56. {
  57. //函数功能:打印操作菜单,选择需要进行的操作,输入1进行内存分配,输入2进行内存去配,输入0退出
  58. int choice;
  59. printf("*********可变分区管理**********\n");
  60. printf(" * 1.内存分配 *\n");
  61. printf(" * 2.内存去配 *\n");
  62. printf(" * 0.退出 *\n");
  63. printf(" 请输入选项[ ]\b\b");
  64. scanf("%d",&choice);
  65. if(choice == 1)
  66. {
  67. printf("1.内存分配\n");
  68. reorder(head);
  69. print(head);
  70. head=allocate(head);
  71. }
  72. else if(choice == 2)
  73. {
  74. printf("2.内存去配\n");
  75. reorder(head);
  76. print(head);
  77. head=recyle(head);
  78. }
  79. else
  80. {
  81. return NULL;
  82. }
  83. return head;
  84. }
  85. //函数名:allocate 参数:node* head
  86. node* allocate(node *head)
  87. {
  88. //函数名:输入作业名和大小,默认采用最先分配
  89. char name[20];
  90. int jobsize;
  91. printf("请输入作业名:");
  92. scanf("%s",&name);
  93. printf("请输入%s需要分配的主存大小:",name);
  94. scanf("%d",&jobsize);
  95. if(jobsize <= g_size)
  96. head = firstAllocation(head,jobsize,name);
  97. else
  98. printf("分配失败!");
  99. return head;
  100. }
  101. //函数名:firstAllocation 参数:node* head,int size,charc[10]
  102. node* firstAllocation(node* head,int size,char c[10])
  103. {
  104. //函数功能:对作业进行分段,并采用最先分配,分段结束后打印 段表
  105. int count = 0,blockNum,jobblocksize,state;
  106. node *q,*pre;
  107. segmentNode* D = (segmentNode *) malloc ( sizeof(segmentNode) * 1 );
  108. D->next = NULL;
  109. strcpy(D->jobname,c);
  110. if(duanbiao == NULL)
  111. duanbiao = D;
  112. else
  113. {
  114. D->next = duanbiao;
  115. duanbiao = D;
  116. }
  117. q = head;
  118. printf("请输入要分成几段:");
  119. scanf("%d",&blockNum);D->sum = blockNum;
  120. while(count != blockNum)
  121. {
  122. printf("剩余%dKB的内存,请输入第%d段的大小:",size,count+1);
  123. scanf("%d",&jobblocksize);
  124. node* p = (node *) malloc ( sizeof(node) * 1 );
  125. p->next = NULL;
  126. p->size = jobblocksize;
  127. strcpy(p->flag,c);
  128. // p->flag[strlen(p->flag)+1] = p->flag[strlen(p->flag)];
  129. // p->flag[strlen(p->flag)]= '0' + count;
  130. state = count;
  131. while(1)
  132. {
  133. if(state/10 == 0)
  134. {
  135. p->flag[strlen(p->flag)+1] = p->flag[strlen(p->flag)];
  136. p->flag[strlen(p->flag)]= '0' + state%10;
  137. break;
  138. }
  139. else
  140. {
  141. p->flag[strlen(p->flag)+1] = p->flag[strlen(p->flag)];
  142. p->flag[strlen(p->flag)]= '0' + state/10;
  143. state=state%10;
  144. }
  145. }
  146. while(q!=NULL)
  147. {
  148. if(q->size >= p->size)
  149. break;
  150. pre = q;
  151. q = q->next;
  152. }
  153. if(q!=NULL)
  154. {
  155. p->address = q->address;
  156. if(q->size == p->size)
  157. {
  158. if(q==head)
  159. head=NULL;
  160. else
  161. pre->next = q->next;
  162. }
  163. else
  164. {
  165. q->size = q->size -p->size;
  166. q->address = q->address + p->size;
  167. }
  168. if(distribute == NULL)
  169. {
  170. distribute = p;
  171. }
  172. else
  173. {
  174. p->next = distribute;
  175. distribute = p;
  176. }
  177. }
  178. else
  179. {
  180. printf("分配失败!");
  181. return head;
  182. }
  183. D->a[count][0] = jobblocksize;
  184. D->a[count][1] = p->address + p->size;
  185. count++;
  186. size = size - jobblocksize;
  187. reorder(head);
  188. print(head);
  189. }
  190. printf("分配成功!\n");
  191. printf("************打印%s段表************\n",c);
  192. printf("段号\t段长\t基址\n");
  193. for(int i=0;i<blockNum;i++)
  194. printf("%d\t%d\t%d\n",i,D->a[i][0],D->a[i][1]);
  195. return head;
  196. }
  197. //函数名:reorder 参数:node* head
  198. node* reorder(node* head)
  199. {
  200. //函数功能:对分区和未分区的存储区域进行编号
  201. int count;
  202. node *p;
  203. count = 1;
  204. p = distribute;
  205. while(p!=NULL)
  206. {
  207. p->id = count;
  208. count++;
  209. p = p->next;
  210. }
  211. p = head;
  212. while(p!=NULL)
  213. {
  214. p->id = count;
  215. count++;
  216. p = p->next;
  217. }
  218. return head;
  219. }
  220. //函数名:recycle 参数:node* head
  221. node* recyle(node *head) //回收算法
  222. {
  223. //函数功能:对归还分区按情况进行处理,有上邻有下邻,有上邻无下邻,无上邻有下邻,无上邻无下邻
  224. char name[20];
  225. int state;
  226. segmentNode *q,*preq;
  227. node *qq,*preqq,*qqq,*preqqq;//distribute
  228. q = duanbiao;
  229. printf("请输入您想回收的作业名:");
  230. scanf("%s",&name);
  231. while(q!=NULL&&strcmp(q->jobname,name)!=0)
  232. {
  233. preq = q;
  234. q = q->next;
  235. }
  236. if(q==duanbiao)
  237. {
  238. duanbiao=q->next;
  239. }
  240. else
  241. {
  242. preq->next=q->next;
  243. }
  244. if(q==NULL)
  245. printf("没有该作业!");
  246. else
  247. {
  248. for(int i=0;i<q->sum;i++)
  249. {
  250. qq = distribute;//已分配链表
  251. while(qq!=NULL)//在已分配表中找要回收的作业
  252. {
  253. if(qq->address == q->a[i][1]-q->a[i][0])
  254. {
  255. if(qq==distribute)
  256. {
  257. distribute = qq->next;
  258. }
  259. else
  260. {
  261. preqq->next = qq->next;
  262. }
  263. break;
  264. }
  265. preqq = qq;
  266. qq = qq->next;
  267. }
  268. preqqq = NULL;
  269. qqq = head;//未分配链表
  270. while(qqq!=NULL)//将要回收的作业的空闲分区合并
  271. {
  272. if(qq->address+qq->size<head->address)//头没有临界区
  273. {
  274. qq->next = head;
  275. head = qq;
  276. printf("回收%s的段%s成功!\n",name,qq->flag);
  277. qq->flag[0] = '\0';
  278. break;
  279. }
  280. else if(qq->address+qq->size == head->address)//头有下
  281. {
  282. head->address = qq->address;
  283. head->size = head->size + qq->size;
  284. printf("回收%s的段%s成功!\n",name,qq->flag);
  285. break;
  286. }
  287. else if(preqqq!=NULL&&qq->address == preqqq->address+preqqq->size&&qq->address+qq->size==qqq->address)//有上有下
  288. {
  289. preqqq->size = preqqq->size+qqq->size+qq->size;
  290. preqqq->next = qqq->next;
  291. printf("回收%s的段%s成功!\n",name,qq->flag);
  292. free(qq);
  293. break;
  294. }
  295. else if(preqqq!=NULL&&qq->address == preqqq->address+preqqq->size&&qq->address+qq->size<qqq->address)//有上没有下
  296. {
  297. preqqq->size =preqqq->size + qq->size;
  298. printf("回收%s的段%s成功!\n",name,qq->flag);
  299. free(qq);
  300. break;
  301. }
  302. else if(preqqq!=NULL&&qq->address > preqqq->address+preqqq->size&&qq->address+qq->size==qqq->address)//没有上有下
  303. {
  304. qqq->address = qq->address;
  305. qqq->size = qqq->size+qq->size;
  306. printf("回收%s的段%s成功!\n",name,qq->flag);
  307. free(qq);
  308. break;
  309. }
  310. else if(preqqq!=NULL&&qq->address > preqqq->address+preqqq->size&&qq->address+qq->size<qqq->address)//没有上没有下
  311. {
  312. qq->next = qqq;
  313. preqqq->next = qq;
  314. printf("回收%s的段%s成功!\n",name,qq->flag);
  315. qq->flag[0] = '\0';
  316. break;
  317. }
  318. else if(preqqq!=NULL&&qqq->next == NULL&&qqq->address+qqq->size==qq->address)//尾部(有上)
  319. {
  320. qqq->size = qqq->size+qq->size;
  321. printf("回收%s的段%s成功!\n",name,qq->flag);
  322. break;
  323. }
  324. else if(preqqq!=NULL&&qqq->next == NULL&&qqq->address+qqq->size<qq->address)// 尾部(没有上)
  325. {
  326. qqq->next = qq;
  327. qq->next =NULL;
  328. printf("回收%s的段%s成功!\n",name,qq->flag);
  329. qq->flag[0]='\0';
  330. break;
  331. }
  332. preqqq = qqq;
  333. qqq = qqq->next;
  334. }
  335. }
  336. reorder(head);
  337. print(head);
  338. free(q);
  339. }
  340. return head;
  341. }
  342. //函数名:print参数:node* head
  343. void print(node* head)
  344. {
  345. //函数功能:打印主存分配表
  346. node *p;
  347. printf("******************主存分配情况******************\n");
  348. p = distribute;
  349. printf("已分配:\n");
  350. printf("分配号 大小(KB) 起始(KB) 状态\n");
  351. while(p!=NULL&&p->flag[0]!='\0')
  352. {
  353. printf("%d\t%d\t\t%d\t\t%s\n",p->id,p->size,p->address,p->flag);
  354. p = p->next;
  355. }
  356. printf("\n\n\n");
  357. p = head;
  358. printf("未分配:\n");
  359. printf("分配号 大小(KB) 起始(KB) 状态\n");
  360. while(p!=NULL&&p->flag[0] == '\0')
  361. {
  362. printf("%d\t%d\t\t%d\t\t空闲\n",p->id,p->size,p->address,p->flag);
  363. p = p->next;
  364. }
  365. }
  366. int main()
  367. {
  368. node* head;
  369. head=initMemory();
  370. while(1)
  371. {
  372. head=operation(head);
  373. if(head==NULL)
  374. {
  375. break;
  376. }
  377. }
  378. return 0;
  379. }

运行结果

实验总结

①对单链表还是不熟,没有头结点的单链表head没有next;

②对链表的遍历条件没有设计好,在该题中preqqq!=NULL才能进行遍历;

③对于指针,如果修改了指针则要返回该指针并赋值给它本身,或者在传递指针时,传的是指针的指针,否则对指针的处理是无效的。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号