Re: [問題] delete / new , free / malloc
這篇回覆實驗性質頗重,看笑話的網友請海涵,
觀念有誤請指正。
花了點時間看系列文,發現源起是 QQ29 誤會大了。
提供相異於 littleshan 之看法 ( L 大之回覆均精彩,值得細閱。)
※ 引述《QQ29 (我愛阿蓉)》之銘言:
: new / delete vs malloc / free
: 請教各位一個小問題
: 我看msdn的一個sample code
: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365917(v=vs.85).aspx
先拋開 new/delete 與 malloc/free 之關係,
msdn 上用的這例子明顯是以 C language 為編譯,
這應是最大之誤會 - 一開始就打算不用 c++ 之運算子。
故它並不調用 new / delete ,而是使用 malloc / free,
而其範例所使用之結構體 PIP_ADAPTER_INFO 內容也實屬 POD,
與 c++ 中之 class 有所些許差異。
此時即使換 c++ 之 new, struct 裡頭全都是 POD,
扣除 allocate fail 之例外處理,我想不到對這特例而言,
new/delete 與 malloc/free 有何差異。
: 這底下有一個sample
: 有這行
: pAdapterInfo = (IP_ADAPTER_INFO *) MALLOC(ulOutBufLen);
: 他使用了malloc
: 但聽說 能用new / delete 就盡量用
這是個可以讓人爭論很久的問題,所有的「聽說」都該再「了解」背後原因。
會有此說起因大多是在於 constructor 是否會被隱喻喚起,
小處在於例外處理之部份。
在 C++,我較偏向於,POD 時採用 malloc/free 做處理,
遇到 struct (即使 struct 裡也全為 POD,沒任何 member function) 時,
則採用 new。
照我的邏輯走,會有個缺點 - 維護上並沒 new 來得容易,
看看下面這程式碼
typedef int PointType;
const size_t cnt = 10;
PointType *a = (PointType*)malloc(sizeof(PointType)*cnt);
free(a);
但若哪天要把 PointType 換成 class 的時候這段 code 就出包了
typedef CPoint PointType;
const size_t cnt = 10;
PointType *a = (PointType*)malloc(sizeof(PointTYpe)*cnt);
free(a);
在 malloc 那裡反而中了不會喚起 constructor 的致命傷,
推估這是被大家所推,盡量使用 new 不用 malloc 之「其中一個原因」。
至於其它的原因於此便不再深入探討。
: 所以
: 我想使用new 這operator來做
: 但有個疑問
: ulOutBufLen 這個值 有可能 "大於" sizeof(IP_ADAPTER_INFO).
: 假如我用
: pAdapterInfo = (IP_ADAPTER_INFO *) new char[ulOutBufLen];
: 這樣安全嗎
: 如果沒問題的話
: 我使用
: delete pAdapterInfo; 就能把這一串連續空間標記起來嗎?
: 我是不曉得他delete怎麼去判定
: 他連續空間哪一段是他配置的
: 我很怕
: delete pAdapterInfo; 只是把sizeof(IP_ADAPTER_INFO)byte的記憶體給標記
: 而實際上
: 我是需要delete 掉sizeof(IP_ADAPTER_INFO) bytes的資訊.
: 相較於delete / new
: malloc / free 是不是就沒這問題了?
: free(pAdapterInfo) 他就是會從 這個起始位址 free到 他剛剛配置的空間的結尾. 因為
: 我看他範例就直接free了...
: ps.請問有沒有什麼方式 可以驗證 我確實delete 標記掉了多少byte嗎?
: 因為我也不知道我自己這樣寫有沒有問題~~ 謝謝
: 謝謝
上面這一段一直在做 malloc / new 的比較,你怕 malloc 和 new 所配置的空間不一樣
也怕 delete / free 所釋放的空間不一樣,整體來說就是怕它們對於記憶體掌握管理方
式不一樣。 不知我的理解是否正確?若是的話再繼續往下看。
我於最原始的文章之推文裡給了一道線索 - 直接下斷點追new源碼怎麼寫的。
既然你 compiler 是 vc, 來 trace vc 裡面的重點碼, 我 trace 是 dbg 版的 dll。
先看單純的 malloc 和 free,追蹤下來可以發現
ˇ malloc 實際上的核心 code 是在呼叫 _nh_malloc_dbg (dbgmalloc.c)
ˇ free 實際上的核心 code 是在呼叫 _free_dbg (dbgfree.c)
過程會調用一些內部判斷機制沒錯,
若再以單純的 int *a=new int; delete a; 來追蹤
ˇ new 實際上的核心 code 是直接呼叫 malloc,只是多了判斷 malloc 回傳值是否
為 0 (也就是 malloc fail),如果 malloc 傳回 0 的話丟出 (raise) 例外
static const std::bad_alloc nomem; (new.cpp, newaop.cpp)
ˇ delete 實際上的核心 code 是在呼叫 _free_dbg (dbgdel.cpp, dbgdel2.cpp)
也和 free 一樣。
---
上面的說明只顯示了,new/delete 和 malloc/free 底層是調用的是同一套函式庫,
差在細節上有些不同,也由於細節不同 (這裡不再解析下去,再拆下去會很可怕),
所以才有一種說法: 即使對於 POD 而言, new/delete, malloc/free 還是不能混用。
甚至,我也不確定標準裡是否有明定, new/delete, malloc/free 在底層調用的函
式庫一定要同一組,所以 trace 後我也只把這個當作 vc 的一種特例而已。
( 雖然即使標準沒明定,我想大多 compiler 也可能會貪懶底層用同一組去做 )
----
而再回到你的問題,如果 malloc / free 可以,
明明底層調用的是同一套 library,為何調用 new / delete 便不行?
如果你的問題是:為什麼別人說盡量用 new/delete,而這個範例是用 malloc/free,
答案是:msdn 的這個範例是要用 C compiler 的,所以避開了 C++ 的東西。
----
以上淺見,歡迎討論與指正。
--
世界上有種,
將 不可能 轉換為 無限可能 的強大力量,
我稱它為 - 信念。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.69.239
※ 編輯: tropical72 來自: 180.177.69.239 (01/12 04:41)
→
01/12 09:04, , 1F
01/12 09:04, 1F
推
01/12 14:41, , 2F
01/12 14:41, 2F
推
01/12 16:29, , 3F
01/12 16:29, 3F
→
01/12 17:06, , 4F
01/12 17:06, 4F
→
01/12 17:07, , 5F
01/12 17:07, 5F
→
01/12 17:07, , 6F
01/12 17:07, 6F
→
01/12 17:23, , 7F
01/12 17:23, 7F
→
01/12 20:06, , 8F
01/12 20:06, 8F
→
01/12 20:06, , 9F
01/12 20:06, 9F
推
01/12 23:23, , 10F
01/12 23:23, 10F
→
01/12 23:24, , 11F
01/12 23:24, 11F
→
01/13 08:42, , 12F
01/13 08:42, 12F
→
01/13 08:44, , 13F
01/13 08:44, 13F
→
01/13 08:45, , 14F
01/13 08:45, 14F
推
01/14 10:06, , 15F
01/14 10:06, 15F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 6 之 7 篇):