1. 程式人生 > >malloc到未初始化的記憶體

malloc到未初始化的記憶體

在最近開發過程中發現一個malloc到未初始化記憶體的錯誤.

在使用CLISH(一款命令列開源軟體)的時候,每次這個程式退出的時候都會發生core dump,錯誤為invalid pointer: 0x00007ffff02b35d8 .

但是這個錯誤只在某一臺機器上發生錯誤,在完全相同配置(軟硬體)的另外一臺機器的時候,並不發生錯誤,調整clish載入的xml檔案的之後,這個錯誤也會消失.

通過gdb除錯發現core發生在free一個ptype_t指標的時候發生的錯誤,並且該指標地址為一個非法地址,這個指標指向的結構是一個聲明瞭引用,但是並沒有宣告定義的型別(PTYPE).

在宣告這個引用的定義之後,錯誤會消失.

在除錯過程中,在最後free之前將指標指向NULL,就不會發生core.

再最初初始化了這個型別之後,後面有很多的程式碼都有機會更改這個結構的指標,沒辦法搜尋所有程式碼進行分析.

最後把目光轉向初始化

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;
}
這個函式初始化之後,就進行init,填充指標指向的地址,但是由於這個型別沒有定義,所以有些內容就不會被填充,如果malloc的地址又是一個未初始化的地址,就會發生最後的invalid pointer錯誤.

這個錯誤其實是配置錯誤,所有在xml引用的型別都應該有定義,有定義的型別都不會發生coredump

從另外一個角度講,這個錯誤也是由於malloc記憶體之後沒有進行初始化,完全信賴後面的init方法會正確進行初始化造成的, 所以這也是一個clish的bug, malloc之後一定要進行初始化, 雖然這個錯誤發生並不是絕對的.

既然建議所有申請的記憶體都要進行初始化,不知道為什麼這個標準api萬年不變呢?

還有一個問題就是這個記憶體釋放發生在程式退出的時機,但是程式退出之後,所有記憶體都要返回給作業系統,那這個記憶體釋放是否是畫蛇添足呢?