malloc到未初始化的記憶體
阿新 • • 發佈:2019-02-03
在最近開發過程中發現一個malloc到未初始化記憶體的錯誤.
在使用CLISH(一款命令列開源軟體)的時候,每次這個程式退出的時候都會發生core dump,錯誤為invalid pointer: 0x00007ffff02b35d8 .
但是這個錯誤只在某一臺機器上發生錯誤,在完全相同配置(軟硬體)的另外一臺機器的時候,並不發生錯誤,調整clish載入的xml檔案的之後,這個錯誤也會消失.
通過gdb除錯發現core發生在free一個ptype_t指標的時候發生的錯誤,並且該指標地址為一個非法地址,這個指標指向的結構是一個聲明瞭引用,但是並沒有宣告定義的型別(PTYPE).
在宣告這個引用的定義之後,錯誤會消失.
在除錯過程中,在最後free之前將指標指向NULL,就不會發生core.
再最初初始化了這個型別之後,後面有很多的程式碼都有機會更改這個結構的指標,沒辦法搜尋所有程式碼進行分析.
最後把目光轉向初始化
這個函式初始化之後,就進行init,填充指標指向的地址,但是由於這個型別沒有定義,所以有些內容就不會被填充,如果malloc的地址又是一個未初始化的地址,就會發生最後的invalid pointer錯誤.clish_ptype_t * clish_ptype_new(const char *name, const char *help, const char *pattern, clish_ptype_method_e method, clish_ptype_preprocess_e preprocess) { clish_ptype_t *this = malloc(sizeof(clish_ptype_t)); memset(this, 0, sizeof(clish_ptype_t)); //這行是後加的 if(NULL != this) { clish_ptype_init(this,name,help,pattern,method,preprocess); } return this; }
這個錯誤其實是配置錯誤,所有在xml引用的型別都應該有定義,有定義的型別都不會發生coredump
從另外一個角度講,這個錯誤也是由於malloc記憶體之後沒有進行初始化,完全信賴後面的init方法會正確進行初始化造成的, 所以這也是一個clish的bug, malloc之後一定要進行初始化, 雖然這個錯誤發生並不是絕對的.
既然建議所有申請的記憶體都要進行初始化,不知道為什麼這個標準api萬年不變呢?
還有一個問題就是這個記憶體釋放發生在程式退出的時機,但是程式退出之後,所有記憶體都要返回給作業系統,那這個記憶體釋放是否是畫蛇添足呢?