C++ new與malloc和delete及free動態(tài)內(nèi)存管理及區(qū)別介紹
一般情況-堆上申請普通變量空間
申請堆空間時,實驗表明 new/malloc 與 delete/free 是可以混用的,即可以通過free()釋放掉new出來的一塊內(nèi)存。
int main() { int *p = new int(123); delete p; //free(p); }
特殊情況-堆上申請對象空間
class Person{ public: Person(){ cout << "construct call ......" << endl; } ~Person(){ cout << "destruct call ......" << endl; } private: int m_age; }; int main() { Person *ptr = new Person(); if (ptr != nullptr) { free(ptr); } return 0; }
單步走看內(nèi)存分布圖:
可以看到,執(zhí)行完free(ptr) 后,內(nèi)存確實是被釋放了。(補充一下:fd作為開始結(jié)束的標(biāo)志,"cd cd cd cd"代表開辟的內(nèi)存,四個字節(jié))
但是!對于一個對象而言,new和delete關(guān)鍵字還額外做了 調(diào)用構(gòu)造函數(shù)和調(diào)用析構(gòu)函數(shù)這兩個步驟。
可以看到,程序只調(diào)用了構(gòu)造函數(shù)(new關(guān)鍵字產(chǎn)生),但是由于使用的是free(),因此并沒有調(diào)用類中的析構(gòu)函數(shù)。
一般情況-堆上申請普通數(shù)組空間
int main() { int *ptr = new int[10]; delete[]ptr; //delete ptr; return 0; }
我們知道,用new在堆上申請數(shù)組空間,一般delete的時候都需要加上[ ] ,即 delete[ ] 。
但實驗表明,如果不涉及到類對象,不加[ ]也同樣可以實現(xiàn)空間的釋放,加不加[ ]是沒有區(qū)別的。
特殊情況-堆上申請對象數(shù)組空間
int main() { Person *ptr = new Person[10]; delete ptr; return 0; }
當(dāng)new一個對象數(shù)組時,如果沒有用delete[ ] ,會發(fā)生崩潰報錯:
修改成delete [ ] ptr后,程序正常運行,并調(diào)用了十次構(gòu)造函數(shù)和十次析構(gòu)函數(shù):
進一步探索:為什么修改為delete [ ] 就會調(diào)用十次析構(gòu)函數(shù)?它是如何知道創(chuàng)建了十個對象就一定會析構(gòu)十個對象?
查看一下此種情況下的內(nèi)存分布:
可以看到我們申請的堆對象數(shù)組空間(10個),仔細查看改起始地址的前一個地址,按道理這并不屬于我們分配的空間,為什么會多一個地址?
0x011E4EC8 ,該地址保存的值顯示為16進制,轉(zhuǎn)換為十進制剛好為10(0a 00 00 00)。這個10代表著什么?
不妨修改一下這個地址,0a 00 00 00 修改成 07 00 00 00 后接著單步走:
此時原來的十個地址空間的確是完整的被釋放了,但是析構(gòu)函數(shù)只被調(diào)用了 7次!正好是自己修改的那個內(nèi)存地址的值。
到這里可以得出結(jié)論: 編譯器是如何記錄new 創(chuàng)建出來數(shù)組對象的個數(shù), 就是簡單的在創(chuàng)建空間的前一個地址,記錄了創(chuàng)建對象的個數(shù),析構(gòu)的時候就按照這個地址的值進行析構(gòu)。
總結(jié)
1. 申請一個堆上的對象時,不允許混搭new/delete 必須搭配使用。
2. new [ ] 和 delete [ ] 一定要配套使用,特別是申請對象數(shù)組時。
3. vs編譯器會在new [ ] 申請對象數(shù)組時,在堆開始的前4個字節(jié)寫入當(dāng)前數(shù)組的長度,用于記錄delete [ ]釋放時候的析構(gòu)函數(shù)調(diào)用。
到此這篇關(guān)于C++ new與malloc和delete及free動態(tài)內(nèi)存管理及區(qū)別介紹的文章就介紹到這了,更多相關(guān)C++動態(tài)內(nèi)存管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一篇文章帶你了解C++Primer學(xué)習(xí)日記--處理數(shù)據(jù)
今天小編就為大家分享一篇關(guān)于C++對數(shù)器的使用講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2021-08-08C++報錯:Id?returned?1exit?status的解決辦法
最近剛學(xué)c語言,不止一次遇到了同一種報錯,經(jīng)過總結(jié)分享給大家,下面這篇文章主要給大家介紹了關(guān)于C++報錯:Id?returned?1exit?status的解決辦法,需要的朋友可以參考下2023-04-04C++ 數(shù)據(jù)結(jié)構(gòu)之對稱矩陣及稀疏矩陣的壓縮存儲
這篇文章主要介紹了C++ 數(shù)據(jù)結(jié)構(gòu)之對稱矩陣及稀疏矩陣的壓縮存儲的相關(guān)資料,這里實現(xiàn)稀疏矩陣和對稱矩陣的壓縮存儲的實例,需要的朋友可以參考下2017-08-08基于C++執(zhí)行內(nèi)存memcpy效率測試的分析
本篇文章對C++中執(zhí)行內(nèi)存memcpy的效率進行了分析測試。需要的朋友參考下2013-05-05C++實現(xiàn)基于靜態(tài)數(shù)組的順序表
這篇文章主要介紹了C++實現(xiàn)基于靜態(tài)數(shù)組的順序表,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-05-05