網站首頁 編程語言 正文
內存管理
在C++中,一個可執行程序的虛擬地址空間可分為,內核、棧、共享庫的內存映射區域、堆、數據區和代碼段,具體分布額如下圖所示:
內核: 操作系統
棧區: 函數的形參,非靜態的局部變量,函數現場保護數據等等,棧是向下增長的。
共享庫的內存映射區域 用于裝載一個共享的動態內存庫。用戶可使用系統接口創建共享內存,做進程間通信。
堆區: 用于程序運行時動態內存分配,堆是可以上增長的。
數據段: 存儲全局數據和靜態數據,分為.bss 和.data 。
代碼段: 可執行的程序(機器指令)和 常量數據。
C的動態內存管理:
new/delete
在C++中 ,關于動態內存的申請,依靠關鍵字new來實現,new在有三種用法:
1.new運算符的使用
示例如下:
int n = 10;
int *ipa = new int (10);
int *ipb = new int [n](10);
int *ipc = new int[n]{1,2,3,4,5,6,7,8};
在這里new主要做了三個操作,
- 申請一個空間
- 在申請的空間中構造一個int 的對象,并將該對象返回到空間中
- 將空間的地址返回
在上述的代碼中,我們可以開辟一個空間如 ipa 所示;我們也可以開辟一組空間如ipb所示;我們也可以開辟一組空間的同時給所有或者部分元素給定初始值如ipc所示。
當然,動態內存的開辟后,需要我們去手動去釋放它,在C++ 中,我們通過delete來釋放內存,如下所示
delete ipa;
delete[]ipb;
delete[]ipc;
如上代碼所示,當我們開辟一個空間時,我們可以直接通過其地址釋放,當我們申請一組空間時,我們需要加上**[]**,需要告訴編譯器,我們要釋放一組內存。
注: 當我們釋放一組內存時,我們不需要在[]里面寫入需要釋放的動態內存的數目,原因是當我們通過new去申請一組動態內存時,編譯器會自動開辟空間去保存new開辟的空間的數目大小,當我們使用delete 來釋放空間時,編譯器會自動去訪問這個空間來查看開辟的內存大小數目。
2.new的函數方法的使用
new當作函數使用時,其功能和malloc及其相似,唯一不同的地方在與 當申請內存失敗時,malloc會返回NULL,因此,我們在每次使用malloc時候必須對指針進行判空;但是new申請內存失敗后是拋出異常,所以需要捕獲異常處理程序;
示例如下:
int n = 10;
int *ipa = (int*)::operator new(sizeof(int));
// (int*)malloc(sizeof(int));
int *ipb = (int*)::operator new(sizeof(int)*n);
// (int*)malloc(sizeof(int)*n);
當然,我們也需要delete去釋放其空間
delete(ipa);
delete(ipb);
3.定位new
定位new的用法主要是,它不會去自己開辟空間,而是一塊已知的內存上分配給一個對象,但是內存上的數據不會被覆蓋或者改寫,其代碼示例如下:
int n = 10;
int* ipa = (int*)malloc(sizeof(int));
int* ipb = (int*)::operator new(sizeof(int) * n);
new(ipa) int(20);
new(ipb) int[]{ 1,2,3,4,5,6,7,8,9 };
并且 ,通過定位new的方法去把已經申請的存在的內存分配的方法,它可以去分配堆里面的內存,也可以去分配棧里面的內存;定位new的方法也可以將原本申請為int類型的內存看成char/double來顯示。
注: 關于C++的內置類型 int/double/char 等等 ,并不是編譯器將其劃分,而是使用者自身,當我們把數據按照4個字節當一個整體來看待,那么其就是整型,若是按照一個字節為一個單位,那就是char類型;若是8個字節看成一個單位,那就是double類型。而數據在內存存儲的值并不會發生任何改變。
new/delete/malloc/free區別
1、new/delete 是C++中的運算符。 malloc / free 是函數。
2、 malloc申請內存空間時,手動計算所需大小,new只需類型名,自動計算大小;
3、 malloc申請的內存空間不會初始化,new可以初始化;
4、 malloc的返回值為void*, 接收時必須強轉,new不需要;
5、 malloc申請內存空間失敗時,返回的是NULL,使用時必須判空;
new申請內存空間失敗時拋出異常,所以要有捕獲異常處理程序;
原文鏈接:https://blog.csdn.net/qq_42795061/article/details/124886205
相關推薦
- 2022-06-14 Pycharm安裝第三方庫的超詳細步驟_python
- 2022-05-05 .NetCore手動封裝日志組件的實現代碼_實用技巧
- 2023-02-14 解決React報錯React.Children.only?expected?to?receive?s
- 2022-09-08 redis?lua限流算法實現示例_Redis
- 2023-03-03 C++?高精度乘法運算的實現_C 語言
- 2022-06-08 Android即時通訊設計(騰訊IM接入和WebSocket接入)_Android
- 2022-03-26 Android?Studio中Logcat寫入和查看日志_Android
- 2022-04-21 Android監聽ScrollView滑動距離的簡單處理_Android
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支