雖然是分類是放在「面試」,其實這不是面試題目,只是如果面試出這題的話,我不確定能給出滿意的回答。

這段 code 是睡前突然想到,筆者以前看到一段,自己想不透為什麼那麼做的 code,憑印象寫一下。

 

Code Snippet
  1. // initialize
  2. const size_t MB = 1024 * 1024 ;
  3. char * reverse  = (char*)malloc(100 * MB);  // (!) Q1
  4.  
  5. // real using variable
  6. const size_t NEED = 2000;
  7. int  * my_var   = malloc(sizeof(*my_var) *  NEED);
  8. int  * tmp;
  9.  
  10. /*    do something    */
  11. free(my_var);
  12. tmp = malloc(sizeof(*tmp));  // (!) Q2
  13. free(tmp);
  14.  
  15. /*  do something  */
  16.  
  17. // at end
  18. free(reverse);
  19. tmp = malloc(sizeof(*tmp)); // (!) Q2
  20. free(tmp);

 

後來看了一些書,推斷可能原因

(1)  Q1 的地方應是為了怕後面在 allocate memory 時,記憶體不夠用,先取得一份出來,等到 allocate fail 時,先發警告訊息給 client,告知所剩記憶體不夠,希望能放一些資源出來,或能讓程式做存檔動作;再不行的話把那 100 MB 放出來,看能不能正常取得。但那份記憶體從頭到底沒在用,我很懷疑會不會被 compiler O.P.T 掉。

(2) Q2 幾乎是被我納為「年度十大納悶程式碼」之首。為何每次在釋放一塊 heap 後,馬上又配置一小塊記憶體、再釋放?唯一的猜測,大概和作業系統對記憶體管理機制有關吧。若作業系統管理的機制是,在 free 時並不馬上釋放,等累積到一定數量,或有 allocate 動作時,再一次進行處理,那麼這麼做的原因倒可以解理。一樣的疑惑 - 會不會被 compiler O.P.T 掉。

edisonx 發表在 痞客邦 PIXNET 留言(2) 人氣()


留言列表 (2)

發表留言
  • novus
  • 說老實話我也不曉得,可能的原因之一如你所說。另一個理由,有些版本的 malloc 事先暖機會比較快,不過通常只有測速的程式碼才會這樣寫。

    至於沒被使用的 malloc/free pair 大部分的編譯器應該都不會進行優化,據我所知好像只有 LLVM 這類實驗型的編譯器會做,但僅限於非常簡單的模式。

    另一方面,有些 C runtime 或 OS(例如Linux) 確實會採取 lazy allocation 政策優化記憶體使用,如果只呼叫 malloc 卻從未使用記憶體,那麼配置的手續並不會完成,就像訂位而未報到一樣。這是執行期發生的事情,與編譯器無關。
  • 先謝謝您的回答。

    說到這..周圍的人幾乎沒人懂 lazy evaluation ( 其實是因為現實生活中,周圍的人都不是工科生 ),但那技巧真的差超多的,高階語言 ( C/C++) 之程式設計師也鮮少在探討,是否有書本 (或文章) 在探討這類型的設計模式?

    edisonx 於 2012/06/22 02:55 回覆

  • novus
  • lazy evaluation 只是一個概念,倒也沒有什麼固定的作法,一般都是依照個別程式的效能瓶頸來決定。

    我沒看過什麼書有系統的介紹這些手法,可能有些偏向實戰的資料結構或演算法會提到。另外 lazy evaluation 這個名詞也是程式語言/編譯器最佳化領域的重要特性,但是和普通程式撰寫所說的 lazy 手法意義有點不一樣,如果你想找資料請多留意一下前後文所指為何。
  • 感謝提點 :)

    edisonx 於 2012/06/26 00:11 回覆

您尚未登入,將以訪客身份留言。亦可以上方服務帳號登入留言

請輸入暱稱 ( 最多顯示 6 個中文字元 )

請輸入標題 ( 最多顯示 9 個中文字元 )

請輸入內容 ( 最多 140 個中文字元 )

請輸入左方認證碼:

看不懂,換張圖

請輸入驗證碼