1. 程式人生 > >日本程序開發式自定義的malloc/free函數(三)-源代碼(ソースコード)

日本程序開發式自定義的malloc/free函數(三)-源代碼(ソースコード)

size span 鏈表 pan ppp 附近 efi ret system

這篇文章終於是貼出了我們的源代碼,實現每個功能也是花費了許多時間,大家在編寫的時候可以多花點時間,多嘗試,多看就能寫出來。

老師的要求不能在程序裏面使用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函數(三)-源代碼(ソースコード)