日本程序开发式自定义的malloc/free函数-源代码(ソースコード)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日本程序开发式自定义的malloc/free函数-源代码(ソースコード)相关的知识,希望对你有一定的参考价值。

这篇文章终于是贴出了我们的源代码,实现每个功能也是花费了许多时间,大家在编写的时候可以多花点时间,多尝试,多看就能写出来。

老师的要求不能在程序里面使用malloc,new什么的,有要求使用链表,所以困扰了很久,在同学的启发下可以直接申请一块数组空间,然后再在这个数组空间下进行操作。

具体这个malloc的实现方法,就是申请空间的时候,如果开始里面没有区块,或者空着的区块就计算它要多少空间,在申请的数组空间上切下来一部分给它,要是有空着的区块>=申请的,就把这块区块给它,如果给的太大了,就把能比Header区大的空间的空间切出来变成一个新的区块,如果只能切比header小的空间,那个小空间就变成了内部碎片了。

free是会在释放某个区块的时候,检查附近的区块是不是空的,是的话,就把他们合在一起减少外部碎片的产生。

先产生的两个区块分别变成首尾的区块,新的区块会从首区块指向旧一点的区块,直到尾区块。

PS:本篇只贴出源代码,为了防止学弟,学妹直接复制,其他的讨论,测试不予贴出。


 

  1 /*
  2  * @ysy_zake 4/26/2017
  3  * */
  4 #include <stdio.h>
  5 #include <unistd.h>
  6 #include <stdlib.h>
  7 
  8 #define sizeOfBlock 24//Headerのサイズを決めます。
  9 static size_t kkkkkk[20000];//配列でスペースを申請します
 10 static void *tempaddress = kkkkkk;//一時的に今のアドレスをキープします
 11 typedef struct Header {
 12     unsigned elementSize;//実際のブロックのサイズ
 13     struct Header *pre, *next;// 前駆と後継ポインタ
 14     int free;//空いているかを示し//1空的、0不是空的
 15     int filling;// アドレスをアライメントしやすいため、フィラーします。
 16     void *pmc;//アドレスの正しさを確認するように使います。
 17     char data[1];
 18 } h_header;//h_headerはHeader*別名であり
 19 typedef struct Header *t_header;//t_headerはHeader*別名であり
 20 t_header temp = NULL;//空きポインタをNULLに初期化します。
 21 t_header getmmm(size_t sss) {//配列のアドレスからスペースを割り当てます
 22     t_header temppppp = (t_header) tempaddress;
 23     size_t fdf = ((size_t) temppppp + (size_t) sss - (size_t) kkkkkk);
 24     if (fdf > 20000) {//もしオーバーフローが発生したらNULLを戻ります。
 25 
 26         return NULL;
 27     }
 28     temppppp += sss;
 29     tempaddress = temppppp;
 30     return (t_header) tempaddress;//申請した新たなアドレスを戻ります。
 31 }
 32 
 33 void *myAlloc(size_t elementSizeTemp) {//オリジナルなmallocであり
 34     if ((int) elementSizeTemp < 0) {//sizeはゼロよりおおきい必要があります
 35         printf("ERROR size<0!");
 36         system("pause");
 37         exit(1);
 38     }
 39     if (elementSizeTemp < 24) {//sizeはheaderよりおおきい必要があります
 40         printf("ERROR size have to bigger than 24!");
 41         system("pause");
 42         exit(1);
 43     }
 44     //アライメントします
 45     size_t tempSize = elementSizeTemp;
 46     t_header curBlock = NULL;
 47     t_header finBlock, tempBlock;//finBlockは前のブラック
 48     if (elementSizeTemp & 0x7 != 0) {//ブロックは8の倍数ではなっかたら、調整します
 49         ((tempSize >> 3) + 1) << 3;
 50     }
 51     if (temp) {//tempはNULLですかを判断します
 52         //NULLではなっかたら
 53         //first-fit ブラックを探す
 54         tempBlock = (t_header) temp;
 55         while (tempBlock && !(tempBlock->free && tempBlock->elementSize >= tempSize)) {//ブラックの中で適当なブラックを探す
 56             finBlock = tempBlock;
 57             tempBlock = tempBlock->next;
 58         }
 59         curBlock = tempBlock;
 60         if (curBlock) {
 61             //ブラックがあったら、このブラックを
 62             if ((curBlock->elementSize - tempSize) >= sizeOfBlock) {
 63                 t_header newblock;//新たなブラックを分離作る
 64                 newblock = curBlock + tempSize;
 65                 newblock->pmc = newblock->data;
 66                 newblock->elementSize = curBlock->elementSize - tempSize - sizeOfBlock;
 67                 newblock->next = curBlock->next;
 68                 newblock->free = 1;
 69                 curBlock->elementSize = tempSize;
 70                 curBlock->next = newblock;
 71             } else {
 72                 printf("size:%d", tempBlock->elementSize);
 73                 printf("Internal fragmentation happened!");
 74                 printf("\n");
 75             }
 76             curBlock->free = 0;//今のブラックを使用中と設定します
 77         } else {
 78             //ブラックがなかったら、新たなブラックを作る
 79             t_header newhead, temphd;
 80             temphd = temp->next;
 81             newhead = getmmm(elementSizeTemp);
 82             if (newhead == NULL) {//もしオーバーフローが発生したら、判断します、プログラムを中止します
 83                 printf("Error overflow!");
 84                 system("pause");
 85                 exit(1);
 86             }
 87             newhead->pmc = newhead->data;
 88             newhead->free = 0;
 89             newhead->elementSize = elementSizeTemp;
 90             newhead->next = temphd;
 91             temp->next = newhead;
 92             curBlock = newhead;
 93         }
 94     } else {//tempはNULLなら
 95         curBlock = getmmm(elementSizeTemp);//新たなtempを作ります
 96         if (curBlock == NULL) {//オーバーフローが発生したら、判断します、プログラムを中止します
 97             printf("Error overflow!");
 98             system("pause");
 99             exit(1);
100         }
101         curBlock->free = 0;
102         curBlock->elementSize = elementSizeTemp;
103         curBlock->next = NULL;
104         curBlock->pre = NULL;
105         temp = curBlock;
106     }
107     return (void *) curBlock;//失敗したときNULLをもどります
108 }
109 
110 t_header get_block(void *p) {//HEADERのアドレスが間違えた時元のアドレスに戻ります
111     t_header t = (t_header) p;
112     p = t->pmc - sizeOfBlock;
113     return (t_header) p;
114 }
115 
116 int validAddr(void *p) {//アドレスは正しいか判断します
117     t_header tt = (t_header) p;
118     if (temp) {
119         if (p > temp && p <= tempaddress) {
120             tt->pmc -= sizeOfBlock;
121             void *t = tt->pmc;
122 
123             return (p == t);//pmcのなかで保存しているアドレスと今のアドレスを比べる
124         }
125     }
126     return 0;
127 }
128 
129 //ブラックを合体します
130 t_header fusion(t_header b) {
131     if (b->next && b->next->free) {//次のブラックと合体します
132         b->elementSize += sizeOfBlock + b->next->elementSize;
133         b->next = b->next->next;
134         if (b->next)
135             b->next->pre = b;
136     }
137     return b;
138 }
139 
140 void myFree(void *block) {//オリジナルなFREE
141     if (block == NULL) {//このポインタはNULLか判断します
142         printf("Error Can‘t free a NULL!");
143         return;
144     }
145     t_header curBlock;
146     //curBlock = (t_header)block;
147     if (validAddr(block)) {//今のアドレスは正しいか判断します
148         curBlock = (t_header) block;
149 
150     } else {
151         curBlock = get_block(block);//アドレスが正しくないなら、修正します
152     }
153 
154     curBlock->free = 1;
155     if (curBlock->pre && curBlock->pre->free)//もし上のブラックは空いています、これとうえのブラック合体します
156         curBlock = fusion(curBlock->pre);
157     if (curBlock->next)//もし次のブラックは空いています、これとうえのブラック合体します
158         fusion(curBlock);
159     curBlock = temp;
160     while (curBlock->next && (curBlock->next->free == 1)) {//ブラックの中であいているブラクラがあるか
161         curBlock = curBlock->next;
162     }
163     if (!(curBlock->next)) {//全てなブッラクはあいています、入り口のTEMPをNULLと設定します
164         temp = NULL;
165     }
166 
167 }
168 
169 void printout() {//中のブラックの状況を表します
170     t_header tempheader;
171     tempheader = temp;
172     while (tempheader) {
173         printf("size:%d free:%d\n", tempheader->elementSize, tempheader->free);
174         tempheader = tempheader->next;
175     }
176 }
177 
178 void Exterfrag() {
179     t_header tempBlock = (t_header) temp;
180     while (tempBlock && !(tempBlock->free)) {
181         tempBlock = tempBlock->next;
182     }
183     if (tempBlock != NULL) {
184         printf("size:%d", tempBlock->elementSize);
185         printf("External fragmentation happened!");
186         printf("\n");
187     }
188 }
189 
190 int main() {
191     int *ppp0 = (int *) myAlloc(10 * sizeof(int));//40これは入り口のTEMPになにます
192     int *ppp1 = (int *) myAlloc(20 * sizeof(int));//80これは最後
193     int *ppp2 = (int *) myAlloc(50 * sizeof(int));//200
194     int *ppp3 = (int *) myAlloc(70 * sizeof(int));//280
195     myFree(ppp3);
196     int *ppp4 = (int *) myAlloc(30 * sizeof(int));//120三番目
197     int *ppp5 = (int *) myAlloc(11 * sizeof(int));//44これは二番目
198     printout();
199     Exterfrag();
200 
201     system("pause");
202     return 0;
203 }

 本人第一次写博客,要是有什么不好的地方请评论留言提出来,要是有帮上忙,请评论留个赞也行,谢谢。

 

以上是关于日本程序开发式自定义的malloc/free函数-源代码(ソースコード)的主要内容,如果未能解决你的问题,请参考以下文章

C++内存管理第一篇:(malloc/deldete和malloc/free)

C语言中已经有了malloc和free,为啥还需要new和delete?

malloc/free 的使用要点

malloc/free 的使用要点

malloc/free函数

Linux 内核 内存管理内存管理架构 ④ ( 内存分配系统调用过程 | 用户层 malloc free | 系统调用层 brk mmap | 内核层 kmalloc | 内存管理流程 )