iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 13
0
自我挑戰組

30 Days 如何把 C 語言偽裝成高階語言 OWO /系列 第 13

Days 13: 垃圾回收器系列:完善 用於標記地址的函數

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

本系列的大綱 傳送門


▌第一次閱讀垃圾回收器系列,可以先看:

垃圾回收器系列 開始第一篇 傳送門


▌前言提要:

上一篇我們假設有這幾個函數:

void free_all_register_address(void);
void register_address(void *address);
void new_1d(void *ptr, int length, int type_side);

free_all_register_address(void) 是給 atexit() 註冊的,
用來釋放 free() 所有曾經分配空間的地址。
register_address(void *address) 是用來註冊、記錄,是標記地址的函數
曾經分配空間的地址。
new_1d(void **ptr, int length, int type_side) 是取替 malloc()用的,
上一篇弄了一個很粗略的實現:

void new_1d(void **ptr, int length, int type_side){
    /*分配記憶體*/
    *ptr = malloc(length * type_side);
    
    /*紀錄地址*/
    register_address(*ptr);
    
    /*註冊 atexit() */
    /*僅在程序第一次執行時呼叫 atexit() */
	static int first_process = 1;
	if (first_process) {
		atexit(&free_all_register_address);  //此函數只會被呼叫一次
		first_process = 0;  //第一次執行的標記
	}
}

分三個部分,
第一,分配記憶體。
第二,紀錄 已經分配的記憶體空間 的地址。
第三,用 atexit() 進行註冊僅一次
有不少問題,但是完善它不是今天的目標。

今天要完善的是標記地址的函數,
void register_address(void *address);


▌完善標記地址的函數:

標記地址需要空間,一個類型為void*的陣列:

void (*address_pool)[];

而需要標記的地址不只一個,不可以宣告一個固定長度的陣列,必須動態

void **address_pool = NULL;
int index = 0; //索引,指向目前可以儲存地址的空間

為了方便起見,目前 address_pool 被宣告為全域變數


▌粗略估計 register_address 的結構

void register_address(void *address){

    /*擴大、重新分配用於儲存記憶體地址的空間*/
    void **temp_ptr = NULL;  //中轉指標
	temp_ptr = (void**)realloc(address_pool, (index + 1) * sizeof(void*)); //擴大空間
    
    /*對realloc分配記憶體的錯誤檢測*/
    if (temp_ptr == NULL) {
        /*錯誤處理*/
	}
    
    /*成功建立的空間分配給address_pool*/
	address_pool = temp_ptr;  //取得中轉指標的地址
    
    /*註冊記憶體地址*/
	address_pool[index] = address;
	index++;  //空間擴大、索引移位
    
}

分為四個部分,

第一,擴大空間
擴大儲存地址的空間,用 中轉指標 + realloc() 。 可參看 Days 9

第二,檢測錯誤
檢測 realloc() 的回傳,進行錯誤處理

第三,分配成功建立的空間
檢測沒有錯誤,把成功建立的空間(中轉指標)的地址分配給 address_pool 。

第四,註冊地址
把傳入的參數 address,放入新擴大的空間( address_pool[index] )中,
索引 + 1,指向新的儲存地址的空間。


▌所以現在只要

register_address( /*某個地址*/ );

就醬把地址成功記錄下來了。


上一篇
Days 12: 垃圾回收器系列:概念、粗略實現
下一篇
Days 14: 垃圾回收器系列:完善 用於釋放所有被標記地址的函數
系列文
30 Days 如何把 C 語言偽裝成高階語言 OWO /31

尚未有邦友留言

立即登入留言