▌第一次閱讀本系列的,可以先看:


▌閱讀本文章的垃圾回收器系列前:

而 Days 8: 重溫指標:雜項:指標宣告、運算符 是基礎知識及雜項,不看不影響本系列閱讀。
對如何動態分配記憶體( malloc, calloc, realloc, free )不熟悉的:
Days 9: 動態記憶體分配:malloc()、calloc()、realloc()、free(),內存洩露
不知道什麼是 垃圾回收器 的:
Days 11: 什麼是垃圾回收器?
其實還有一點點知識點沒有包括,
不過已經可以開始嘗試實現垃圾回收器~!

▌垃圾回收器的粗略實現:

今天只是粗略實現,之後再具體實現,
首先,正常的做法是怎樣?
int *ptr = (int*)malloc(10 * sizeof(int));
free(ptr);
我們想要怎樣?
int *ptr = (int*)malloc(10 * sizeof(int));
簡單來講,就是想要 分配記憶體後不需要理會釋放的問題
即是 自動的記憶體管理
現在我們手上有一個很有趣的材料:
atexit();
可以在 主程序結束時調用函數

▌欸??!

int *ptr = (int*)malloc(10 * sizeof(int));
atexit(free(ptr));
咳咳,當然不能這樣, atexit() 不能接受有參數的函數
同時 函數地址 也不能帶有默認參數
但是方向很正確。

我們需要一個 沒有參數也沒有回傳 的函數,
放入 atexit() 中註冊,使該函數在主程序結束時調用
進行 free() 的工作。

▌所以肯定有一個這樣的函數存在:

void a_function_for_atexit_to_register(void){
    //somethings to free()
}
而它能夠知道或紀錄著, (【標記-清除】)
曾經分配的記憶體空間的地址。
然後遍歷去釋放。 (【標記-清除】)
這正是 【標記-清除】 的概念。
而這個函數負責釋放的部分。

這個函數能夠知道 曾經分配的記憶體空間的地址,
但它不能存在參數,所以無法傳入地址進行紀錄
代表會有 另一個函數 用於進行 地址的紀錄
void a_function_for_register_address(void *address){
    //save the address 
}
我們還要用一個新的函數去取代 malloc(),有兩種形式:
void *my_malloc(int size);
void my_malloc(void **ptr, int size, int type_side);

▌粗略估計 my_malloc() 的實現:

void my_malloc(void **ptr, int size, int type_side){
    /*分配記憶體*/
    *ptr = malloc(size * type_side);
    
    /*紀錄地址*/
    a_function_for_register_address(*ptr);
    
    /*註冊 atexit() */
    /*僅在程序第一次執行時呼叫 atexit() */
 static int first_process = 1;
 if (first_process) {
  atexit(&a_function_for_atexit_to_register);  //此函數只會被呼叫一次
  first_process = 0;  //第一次執行的標記
 }
}
分三個部分,
第一,分配記憶體。
第二,紀錄 已經分配的記憶體空間 的地址。
第三,用 atexit() 進行註冊,僅一次。

▌小結

現在我們手上有以下函數:
void a_function_for_atexit_to_register(void);
void a_function_for_register_address(void *address);
void my_malloc(void **ptr, int size, int type_side);
改個漂亮一點的名字,按個人習慣吧,
void free_all_register_address(void);
void register_address(void *address);
void new_1d(void **ptr, int length, int type_side);

目前還是很粗糙,不過...


篇幅太長不方便閱讀,下一篇繼續完善。