作者ric2k1 (Ric)
看板EE_DSnP
標題Re: [請益] 兩個getMem裡的sizeof(size_t)...@@
時間Sun Nov 15 01:31:19 2009
※ 引述《a3785lexx (Alex)》之銘言:
: 如題...這個問題困擾我有點久了
: 在MemBlocks::getMem中還有在MemMgr::getMem中
: TODO都有要求要make sure that t % SIZE_T == 0
: 但是我左思右想不得其解...
: 為甚麼t一定要是SIZE_T的倍數不可呢??
因為當你 new 一個變數時,他所指到的記憶體的位置一定是與 SIZE_T 的倍數對齊的,
也就是說,對 32/64 位元的電腦而言,此 memory address 一定是 4/8 的倍數.
你可以試試看,不要用自己的 memory mgr, 就用系統的 new & new [],
無論你寫怎麼樣的 new xxx; 他的記憶體位置一定都是與 SIZE_T 對齊.
: 更精準的來說
: 我不懂的是
: 1.系統在new的時候所傳的參數size_t t是根據data member來決定的
: 正常情況下它有可能會不是SIZE_T的倍數嗎?
: 雖然我覺得應該是有可能,上課投影片的例子newOp.cpp就是一個的感覺@@
: 單一一個A的物件是12這麼大,可是size_t有8這麼大...orz
: 那麼,為甚麼在實作malloc的時候一定要t % SIZE_T == 0呢??
: 如果t不是SIZE_T的倍數會出甚麼問題嗎??
如果不對齊的話下一個取到的記憶體空間可能就不是 SIZE_T 的倍數,
那下一筆資料就會被拆成存放在不同的 word 裏了...
: 呃...等一下...我一邊打這篇請益文一邊想...難道說...
: 要求t一定要是SIZE_T的倍數是為了要能夠達到平台的相容性嗎??
是的,SIZE_T = sizeof(size_t) will be platform dependent.
It will be 4 or 8 for 32 or 64-bit machine.
: 雖然我還是不懂...以本次作業為例,obeject的data member都是char
: char據說是可以一個Byte一個Byte的去吃記憶體的樣子?
: 如果不是以SIZE_T為單位去拿記憶體
: 丟給memTestObj用,就一定會出包,不管char的面子有多大嗎??
不會出包,只是下一個 memTestObj 的記憶體位置會不是 SIZE_T 的倍數...
: 又,如果真的是系統所認定的物件大小size_t t
: 不會是實作記憶體的時候不會出包的大小SIZE_T的倍數
: 那麼我們多丟給這個物件的記憶體,系統會了解嗎??
: 就是它會知道這裡面有多給的不能用的部分嗎?
: 感覺起來有點毛毛的也......o.O
就是會浪費一些記憶體啊...
: 2.如果在new的時候系統丟的size_t t其實一定會是SIZE_T的倍數
: (我記得上課的時候好像是這麼回事啊囧?
: 上課的時候去算一個物件的大小最後都會取tosizeT說orz)
: 也就是如果我剛剛腦包了,1.的問題根本不存在的話....囧
: 那麼,TODO裡的make sure....只是要我們assert它嗎XD?
就是系統丟 size_t t 不一定會是 SIZE_T 的倍數,
所以才要你寫 getMem() 的時候要確認.
: 順帶一提,free的過程只是把記憶體丟給recycleList紀錄而已
: 其實原本的object pointer還是可以去存取這個位置
: 這樣好恐怖的感覺@@"
: 尤其我試了一下...就算是內建的形態也是有這種情況
: 所以在外面寫的人只要一恍神還是會出很嚴重的問題...orz
這種 access freed memory 是很難避免的,除非我們都改成 object,
用 object 來包 pointer, 然後裡頭用個 reference count 來決定 pointer
是否已經沒人在用所以可以 reset 了.
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.224.45.175
1F:推 a3785lexx:恩恩!我的確有自己寫一些小程式來作實驗 11/15 02:20
2F:→ a3785lexx:可是囧的就是我寫出來記憶體位置之間都是差sizeof(Obj) 11/15 02:21
3F:→ a3785lexx:不知道是哪裡沒有搞清楚...XD 11/15 02:21
4F:推 a3785lexx:感謝教授的回覆! 11/15 02:26
5F:→ ric2k1:compiler 傳給 new 的是 sizeof(Obj), 但是你要在 getMem() 11/15 10:51
6F:→ ric2k1:裡頭 allocate SIZE_T 倍數的記憶體, 並且將return ptr設對 11/15 10:52
7F:推 a3785lexx:恩恩!非常感謝老師的回答!我終於了解到底作業要怎麼寫 11/16 20:12
8F:→ a3785lexx:了...XD 11/16 20:12
9F:→ a3785lexx:但是我感到奇怪的是,我自己寫小程式不去overload 11/16 20:13
10F:→ a3785lexx:operator new的時候,我去生成一串array然後看它們的 11/16 20:13
11F:→ a3785lexx:位置...它們不一定是差sizeof(size_t)...我就糊塗了XD 11/16 20:14