去年分析iPhone/iPodTouch上的資料庫檔案iTunesDB的時候,曾經研究過Winamp下的一個關於這個資料庫的開源外掛程式ml_ipod.dll,關於這個資料庫的格式就不在這裡詳述了。只是在移植其中的代碼的時候,發現了記憶體流失問題,而後通過跟蹤原始碼才發現這和strdup的使用有關係,於是Google了一把,找到了一篇文章,文章中解釋了為什麼要放棄strdup。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
最近在看別人編寫的C語言原始碼,很多人喜歡使用strdup來複製字串,我覺得這個習慣不好,因為如果想使自己的程式移植性更好的話,就忘記有這個函數吧。我否定它的主要原因是:
1)用strdup函數的時候,往往我們會忘記記憶體的釋放,可能的原因是對於C庫函數的瞭解不夠,畢竟是其他模組分配記憶體,自己模組釋放它。
2)在不同的平台上,我們對於strdup記憶體配置的函數可能採用不同的方法,比如在某些C庫中用malloc來分配,而在某些C++庫中,用new來分配(因為C++庫可能重寫了相關的C庫代碼)。所以對使用者在釋放它的時候產生了很大的疑惑,是用free還是用delete[]來釋放所分配的記憶體呢?!如果我們主管臆斷,用free來釋放它,操作未知。可能工作正常,可能是部分記憶體流失,也可能是程式崩潰。自己程式的正確性依賴於編譯器,很不爽吧!
我覺得,在模組中,除非萬不得已自己分配的記憶體需要其他模組釋放,否則應該自產自銷,盡量避模組之間的這種耦合性,減少記憶體流失的因素。那麼讀者可能會問,如果字串複製經常用到,類似於下面的一個代碼
char *dest = malloc(strlen(src) + 1);
assert(dest != NULL);
strcpy(dest, src);
經常要被使用,寫3行代碼比較羅嗦,那麼不妨使用宏來搞定它吧。這樣做的好處是確定了記憶體是用malloc分配的,移植性好多了,難道不是嗎?!此外,自己定義的宏,分配記憶體後要釋放,總不會忘記吧。
上述僅僅是個人的觀點,僅供參考!