用c语言实现伙伴系统,需要详细注释
时间: 2023-06-18 21:02:08 浏览: 248
伙伴算法是一种非常有效的内存管理算法,主要用于解决内存碎片化的问题。实现伙伴算法需要实现以下两个功能:
1. 分配内存块
2. 释放内存块
下面是用 C 语言实现伙伴算法的代码:
```
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAXSIZE 10 // 内存块的最大大小
#define MINBSIZE 4 // 最小的内存块大小
int pow2(int n) { // 计算 2^n 的值
return (int) pow(2, n);
}
int buddy(int x, int n) { // 计算 x 的伙伴块号
return x ^ pow2(n);
}
int log2(int n) { // 计算 log2n 的值
int i = 0;
while (n > 1) {
n = n / 2;
i++;
}
return i;
}
int alloc(int n, int *b) { // 分配内存块
int i, j, k;
if (n > MAXSIZE || n < 1) {
printf("Invalid memory size\n");
return -1;
}
n = pow2(ceil(log2(n))); // 找到比 n 大的最小的 2 的幂
for (i = log2(n) - MINBSIZE; i >= 0; i--) {
for (j = 0; j < pow2(i); j++) {
if (b[pow2(i) + j] == 0) {
k = buddy(pow2(i) + j, i + MINBSIZE);
if (b[k] == 0) {
b[pow2(i) + j] = n;
b[k] = 1;
return pow2(i) + j;
}
}
}
}
printf("No memory available\n");
return -1;
}
int dealloc(int x, int *b) { // 释放内存块
int i, buddy, tmp;
if (x < 0 || x >= pow2(MAXSIZE) || b[x] == 0) {
printf("Invalid block or already free\n");
return -1;
}
for (i = log2(b[x]) - MINBSIZE; i >= 0; i--) {
buddy = buddy(x, i + MINBSIZE);
if (b[buddy] == 0) {
break;
}
if (buddy < x) {
tmp = x;
x = buddy;
buddy = tmp;
}
b[x] = 0;
b[buddy] = 0;
x = pow2(i + MINBSIZE) + (x / pow2(i + MINBSIZE + 1));
}
b[x] = 0;
return 0;
}
int main() {
int i, j, k, n;
int mem[pow2(MAXSIZE)] = { 0 };
printf("Enter memory size: ");
scanf("%d", &n);
while (1) {
printf("\nEnter 1 to allocate memory, 2 to free memory, 3 to exit: ");
scanf("%d", &i);
switch (i) {
case 1:
printf("\nEnter block size: ");
scanf("%d", &j);
k = alloc(j, mem);
if (k == -1) {
break;
}
printf("\nAllocated block %d of size %d\n", k, j);
break;
case 2:
printf("\nEnter block number to free: ");
scanf("%d", &j);
dealloc(j, mem);
printf("\nFreed block %d\n", j);
break;
case 3:
exit(0);
default:
printf("\nInvalid choice\n");
}
printf("\nMemory map:\n");
for (j = 0; j < pow2(log2(n)); j++) {
printf("%2d ", mem[j]);
}
printf("\n");
}
return 0;
}
```
代码中有一些函数需要解释:
1. `pow2(int n)`:计算 2^n 的值。
2. `buddy(int x, int n)`:计算 x 的伙伴块号。
3. `log2(int n)`:计算 log2n 的值。
4. `alloc(int n, int *b)`:分配内存块。
5. `dealloc(int x, int *b)`:释放内存块。
代码中使用了一个数组 `mem` 来表示内存块的使用情况,数组的每个元素表示一个内存块,如果该元素的值为 0,表示该内存块未被使用,否则表示该内存块已被分配。在 `alloc` 函数中,从小到大遍历所有可能的内存块,找到第一个大小适合的未被分配的内存块,然后将该内存块从数组中标记为已分配(即将元素的值设置为分配的内存块大小),同时标记该内存块的伙伴块。在 `dealloc` 函数中,先判断要释放的内存块是否合法,然后遍历该内存块的所有祖先块直到找到一个未被分配的伙伴块,将这两个块标记为未分配,然后将指针指向更高一级的块。如果该内存块的所有祖先块都已被分配,则将该内存块标记为未分配。
运行程序后,输入内存大小,然后输入 1 分配内存块,输入 2 释放内存块,输入 3 退出程序。每次操作后将显示内存块的使用情况。
阅读全文