您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“c/c++中如何實現內存管理”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“c/c++中如何實現內存管理”這篇文章吧。
內存區域:
由這張圖我們可以看到程序在內存中的分布,不同的變量存放在不同的區域,而內核空間是用戶無法進行讀寫的用來存儲有關的信息。
要注意棧向下生長,堆向上生長,堆棧相對而生,我們今天主要談在堆上申請空間的相關知識,我們知道在c語言中想要在堆上申請空間需要用到malloc、realloc、calloc這類函數,關于這些函數的相同與不同點大家可以參考我的另一篇博客。
在c++中我們用心的關鍵字 new、delete完成對空間的申請和釋放。語法是也是定義一個指針變量接受開辟的地址,int p=new int;c++允許我們對申請的空間初始化,只要在后面跟上(),()內為要初始化的內容即可。同時也可以用int p=new int[];的方式申請連續的內存空間,這種方式在釋放時的方式為delete [] p;。
注意:在申請自定義類型時new和malloc是類似的,那么意味著對于內置類型free和delete是可以混合使用的,用new申請的空間用free釋放也不會出現什么錯誤,而對于用戶自定義類型new和delete會分別調用構造函數和析構函數,而malloc和free則不會,malloc申請的是與對象大小相同的一塊內存空間,是不會構成對象的,所以我們在申請和釋放空間時要注意配對!
我們在這里談談malloc的原理:我們知道malloc申請大小為10個字節的空間時系統會為我們申請大于十個字節的空間,大概申請來的空間是長這個樣子滴:
這也就是我們在free的時候系統會知道free多少個字節,因為在這個類似于結構體的結構內最前面已經保存了我們申請空間大小的數值了。
這兩個函數是new和delete在底層調用的函數,也就是這兩個函數為我們完成了內存的開辟和釋放。
我們首先看看operator new這個函數:
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc) { // try to allocate size bytes void *p; while ((p = malloc(size)) == 0) if (_callnewh(size) == 0) { // report no memory // 如果申請內存失敗了,這里會拋出bad_alloc 類型異常 static const std::bad_alloc nomem; _RAISE(nomem); } return (p); }
從這個函數我們可以看到底層也是通過malloc實現的,那么malloc申請成功則直接返回,malloc申請失敗嘗試執行空間不足的應對措施,執行這個措施就會繼續申請,否則拋出異常。所以new函數一般都不會申請失敗。
我們再來看operator delete這個函數:
void operator delete(void *pUserData) { _CrtMemBlockHeader * pHead; RTCCALLBACK(_RTC_Free_hook, (pUserData, 0)); if (pUserData == NULL) return; _mlock(_HEAP_LOCK); /* block other threads */ __TRY /* get a pointer to memory block header */ pHead = pHdr(pUserData); /* verify block type */ _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); _free_dbg( pUserData, pHead->nBlockUse ); __FINALLY _munlock(_HEAP_LOCK); /* release other threads */ __END_TRY_FINALLY return; }
通過這個我們知道底層也是通過free實現的就ok。
我們再看看對于自定義類型new和delete的原理:
new的原理
調用operator new函數申請空間
在申請的空間上執行構造函數,完成對象的構造
delete的原理
在空間上執行析構函數,完成對象中資源的清理工作
調用operator delete函數釋放對象的空間
new T[N]的原理
調用operator new[]函數,在operator new[]中實際調用operator new函數完成N個對象空間的申
請
在申請的空間上執行N次構造函數
delete[]的原理
在釋放的對象空間上執行N次析構函數,完成N個對象中資源的清理
調用operator delete[]釋放空間,實際在operator delete[]中調用operator delete來釋放空間
最后的最后我們再細談一下malloc和new的區別:
1.new是操作符、malloc是函數
2.new可以完成對開辟空間的初始化、malloc則不能
3.malloc在使用時需要計算所開辟內存的大小(字節)并傳遞,而new只需跟上類型即可
4.malloc的返回值是void,所以要強制類型轉化,new后是類型則不需要。
5.malloc申請失敗會返回NULL,所以要進行判空,new不需要但需要捕獲異常
6.malloc和free不會調用構造和析構函數。
以上是“c/c++中如何實現內存管理”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。