【C++初階】C/C++內存管理

【C++初階】C/C++內存管理

🥕個人主頁:開敲🍉

🔥所屬專欄:C++🥭

🌼文章目錄🌼

1. C/C++內存分布

2. C語言中動態內存管理方式:malloc/calloc/realloc/free

3. C++內存管理方式

? ? 3.1 new/delete操作內置類型

? ? 3.2 new和delete操作自定義類型

4. operator new和operator delete函數

? ? 4.1 operator和operator delete

5. new和delete的實現原理

? ? 5.1 內置類型

? ? 5.2 自定義類型

6. malloc/free和new/delete的區別

1. C/C++內存分布

? 我們來看下面的一段代碼和相關問題。

int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
static int staticVar = 1;
int localVar = 1;
int num1[10] = { 1, 2, 3, 4 };
char char2[] = "abcd";
const char* pChar3 = "abcd";
int* ptr1 = (int*)malloc(sizeof(int) * 4);
int* ptr2 = (int*)calloc(4, sizeof(int));
int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
free(ptr1);
free(ptr3);

}

1. 選擇題

選項: A.棧 B.堆 C.數據段(靜態區) D.代碼段(常量區)
globalVar在哪里?____
staticGlobalVar在哪里?____
staticVar在哪里?____
localVar在哪里?____
num1 在哪里?____
char2在哪里?____
*char2在哪里?___
pChar3在哪里?____
*pChar3在哪里?____
ptr1在哪里?____
*ptr1在哪里?____


2. 填空題

??sizeof(num1) = ____;??

??sizeof(char2) = ____;???strlen(char2) = ____;

??sizeof(pChar3) = ____;???strlen(pChar3) = ____;

??sizeof(ptr1) = ____;

選擇題答案:C、C、C、A、A? ? ? ? ?A、A、A、D、A、B

第一題:globalVar是全局變量,存放于數據段(靜態區)

第二題:staticGlobalVar是靜態變量,存放于數據段(靜態區)

第三題:staticVar是靜態變量,存放于數據段(靜態區)

第四題:localVar是局部變量,存放于棧區

第五題:num1是數組首元素地址,局部變量,存放于棧區

第六題:char2是數組首元素地址,局部變量,存放于棧區

第七題:因為char2是一個數組,*char2就是常量字符串的第一個字符,字符串存于代碼段(常量區),*char2是將存于常量區的常量字符串的第一個字符拷貝存儲到數組中,因此*char2拿到的是存于數組中,也就是存于棧區的數據

第八題:pChar3是指針,指向常量字符串首元素地址,地址存放于棧區

第九題:*pChar3拿到的是存于代碼段(常量區)的字符串的首元素,存于代碼段(常量區)

第十題:ptr1是指針,指向動態開辟的空間首地址,地址存放于棧區

第十一題:*ptr1拿到的是動態開辟的空間中存儲的元素,動態開辟的空間存放于堆區

填空題答案:40、5、4、4、4、4

第一題:sizeof(num1)中的num1代表整個數組,整個數組大小就是10*4=40字節

第二題:sizeof(char2)計算的是指針類型的大小,32位機器下指針大小為4個字節,64位機器下指針大小為8個字節

第三題:strlen(char2)計算的是字符串長度,遇到'\0'停止

第四題:sizeof(pChar3)計算的也是指針類型的大小

第五題:strlen(pChar3)計算的是字符串長度,遇到'\0'停止

第六題:sizeof(ptr1)計算的也是指針類型的大小

? 說明:

又叫堆棧--非靜態局部變量/函數參數/返回值等等,棧是向下增長的。

?堆用于程序運行時動態內存分配,堆是可以上增長的。

?數據段--存儲全局數據和靜態數據。

?代碼段--可執行的代碼/只讀常量。

2. C語言中動態內存管理方式:malloc/calloc/realloc/free

? C語言動態開辟內存的方式:

?? ?int* arr1 = (int*)malloc(sizeof(int) * 4);

? ? int* arr2 = (int*)calloc(10,sizeof(int));
?? ?int* arr3?= (int*)realloc(arr1, sizeof(int) * 40);

? 這里我們用reallocarr1進行增容時,如果是在另外的地方開辟40個字節的空間,realloc會幫我們完成 釋放arr1原來的空間——將arr1指向arr3所在空間的操作。因此無需我們手動free(arr1)

3. C++內存管理方式

??C語言內存管理方式在C++中可以繼續使用,但有些地方就無能為力,而且使用起來比較麻煩,因此C++又提出了自己的內存管理方式:通過newdelete操作符進行動態內存管理。

? ? 3.1 new/delete操作內置類型

?? ?//動態申請一個int大小的空間
?? ?int* a1 = new int;

?? ?//動態申請一個int的空間,并將值初始化為10
?? ?int* a2 = new int(10);

?? ?//動態申請int類型的數組,長度為10
?? ?int* a3 = new int[10];
?? ?a3[0] = 1;
?? ?cout << *a1 << endl;
?? ?cout << *a3 << endl;
?? ?cout << a3[0] << endl;

? ? //釋放a3動態開辟的空間

? ??delete a1;

? ? delete a2;

? ??delete[] a3;

? ? //注:動態開辟的空間delete后必須加上[],否則會報錯

? ? 3.2 new和delete操作自定義類型

? 從上圖可以看出,使用C語言的malloc對類類型開辟空間和使用free釋放空間時,并不會調用類中的析構造函數和析構函數;而用C++的new對類類型開辟空間和使用delete釋放空間時,會調用類中的構造函數和析構函數。

? 而對于int這些內置類型,不管是malloc和free還是new和delete,都是一樣的效果。

??注:對于類類型的數組開辟,釋放空間時同樣需要在delete后加上[],否則會報錯

4. operator new和operator delete函數
? ? 4.1 operator和operator delete

??newdelete是用戶進行動態內存申請和釋放的操作符operator new operator delete
系統提供的全局函數new在底層調用operator new全局函數來申請空間delete在底層通過
operator delete全局函數來釋放空間

? 下面是系統 operator new和operator delete函數底層代碼:

/*

operator new:該函數實際通過malloc來申請空間,當malloc申請空間成功時直接返回;申請空間
失敗,嘗試執行空 間不足應對措施,如果改應對措施用戶設置了,則繼續申請,否
則拋異常。
*/

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);
}

?

/*
operator delete: 該函數最終是通過free來釋放空間的
*/

void operator delete(void *pUserData)
{
????????_CrtMemBlockHeader * pHead;
? ? ? ? RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
????????if (pUserData == NULL)
????????return;

_mlock(_HEAP_LOCK);
__TRY
/* block other threads */
/* 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);
__END_TRY_FINALLY
/* release other threads */

????????return;
}

/*
free的實現
*/

#define free(p) _free_dbg(p, _NORMAL_BLOCK)

? 不需要明白代碼邏輯,只需要知道在調用new和delete時,實際上調用的是operator newoperator delete函數,同時operator new實際也是通過malloc來申請空間的,不同的是,C語言malloc失敗是直接返回NULL,而new失敗是拋異常,同時對于類類型對象還會調用其構造函數;operator delete最終也是通過free來釋放空間的是,不同的是對于類類型,還會調用析構函數

5. new和delete的實現原理
? ? 5.1 內置類型

? 如果是內置類型,new和delete與malloc和free基本是相同的,不同的地方在于:new在申請空間失敗時是拋異常,而malloc申請空間失敗時是返回NULL。

? ? 5.2 自定義類型

new的原理:

? ? 1. 底層是調用operator new函數申請空間,這是一個重載運算符

? ? 2. 在申請類類型的空間時,調用對象的構造函數完成對對象的構造

new[N]的原理:

? ? 1. 調用operator new[]函數,operator new[]調用operator new函數,實際上最終也是調用operator new函數完成N個對象的申請

? ? 2. 申請類類型對象時,調用N次構造函數

delete的原理:

? ? ?1. 釋放類類型的空間時,首先調用對象的析構函數,對動態申請的空間進行釋放

? ? ?2. 底層調用operator delete函數釋放對象的空間,是一個重載運算符?

delete[]的原理:

? ? ?1. 釋放類類型對象時,調用N次析構函數

? ? ?2. 調用operator delete[]函數,operator delete[]調用operator delete函數,實際上最終也是調用operator delete函數完成對N個對象空間的釋放

6. malloc/free和new/delete的區別

??malloc/free和new/delete的共同點是:都是從堆上申請空間,并且需要用戶手動釋放。

? 不同的地方是:

?malloc和free是函數,new和delete是操作符

?malloc申請的空間不會初始化(calloc可以),new可以初始化

?malloc申請空間時,需要手動計算空間大小并傳遞,new只需在其后跟上空間的類型即可,
如果是多個對象,[]中指定對象個數即可

?malloc的返回值為void*, 在使用時必須強轉,new不需要,因為new后跟的是空間的類型

?malloc申請空間失敗時,返回的是NULL,因此使用時必須判空,new不需要,但是new需
要捕獲異常

?申請自定義類型對象時,malloc/free只會開辟空間,不會調用構造函數與析構函數,而new
在申請空間后會調用構造函數完成對象的初始化,delete在釋放空間前會調用析構函數完成
空間中資源的清理釋放

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 創作不易,點個贊唄,蟹蟹啦~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/46294.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/46294.shtml
英文地址,請注明出處:http://en.pswp.cn/web/46294.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

DP學習——組合模式

學而時習之&#xff0c;溫故而知新。 組合模式 和代理模式相比 和代理模式相比&#xff0c;有點類似。引用類和被引用類都繼承于同一個接口類。 但是感覺組合模式是對代理模式的更加豐富化&#xff08;升級版、超進化&#xff09;&#xff0c;集合化或者說聚合化。 組合模…

拉格朗日乘子法和KKT條件

拉格朗日乘子法(Lagrange Multiplier) 和 KKT(Karush-Kuhn-Tucker) 條件是求解約束優化問題的重要方法&#xff0c;在有等式約束時使用拉格朗日乘子法&#xff0c;在有不等約束時使用 KKT 條件。當然&#xff0c;這兩個方法求得的結果只是必要條件&#xff0c;只有當目標函數…

ssrf復習(及ctfshow351-360)

1. SSRF 概述 服務器會根據用戶提交的URL發送一個HTTP請求。使用用戶指定的URL&#xff0c;Web應用可以獲取圖片或者文件資源等。典型的例子是百度識圖功能。 如果沒有對用戶提交URL和遠端服務器所返回的信息做合適的驗證或過濾&#xff0c;就有可能存在“請求偽造"的缺陷…

C#中錯誤與異常處理

1、錯誤和異常 如果程序運行期間發生錯誤&#xff0c;異常就會發生。異常會中止當前的程序流&#xff0c;如果不采取措施&#xff0c;程序將停止運行。 錯誤和異常是兩個不同的概念&#xff0c;但它們都與程序的穩定性和可維護性有關。 1.1、錯誤 錯誤通常是指編譯時的語法錯誤…

FPGA學習筆記(一) FPGA最小系統

文章目錄 前言一、FPGA最小系統總結 前言 今天學習下FPGA的最小系統一、FPGA最小系統 FPGA最小系統與STM32最小系統類似&#xff0c;由供電電源&#xff0c;時鐘電路晶振&#xff0c;復位和調試接口JTAG以及FLASH配置芯片組成&#xff0c;其與STM32最大的不同之處就是必須要有…

關于Hyperf高并發性能的一些配置詳解和硬件推薦

目錄 工作進程的管理 自定義配置示例&#xff08;EasySwoole&#xff09;&#xff1a; 自動生成&#xff1a; 結論&#xff1a; 集群部署與協程數的關系&#xff1a; 設置 max_coroutine 的考慮因素&#xff1a; 集群部署時的配置&#xff1a; 示例配置&#xff1a; C…

鏈表面試練習習題集(Java)

1. 思路&#xff1a; 因為楊輝三角是由二維數組構成&#xff0c;所以要先創建一個二維數組&#xff0c;如何用順序表表示二維數組&#xff0c;可以通過List<List<Interger>>來表示一個二維數組&#xff0c;可以這樣理解&#xff1a;先創建一個一維數組List&#x…

modbus slave 設備通過 網關thingsboard-gateway 將數據上傳到thingsboard云平臺

搭建thingsboard物聯網云平臺花了大量時間&#xff0c;從小白到最后搭建成功&#xff0c;折磨了好幾天&#xff0c;也感謝網友的幫助&#xff0c;提供了思路最終成功搞定&#xff0c;特此記錄。 一、thingsboard環境搭建&#xff08;Ubuntu20.04LTS&#xff09; 參考官方文檔&a…

java之 junit單元測試案例【經典版】

一 junit單元測試 1.1 單元測試作用 單元測試要滿足AIR原則&#xff0c;即 A&#xff1a; automatic 自動化&#xff1b; I: Independent 獨立性&#xff1b; R&#xff1a;Repeatable 可重復&#xff1b; 2.單元測試必須使用assert來驗證 1.2 案例1 常規單元測試 1.…

PSINS工具箱函數介紹——r2d

介紹工具箱里面r2d這個小函數的作用。 程序源碼 function deg r2d(rad) % Convert angle unit from radian to degree % % Prototype: deg r2d(rad) % Input: rad - angle in radian(s) % Output: deg - angle in degree(s) % % See also r2dm, r2dms, d2r, dm2r, dms2r% …

設計模式使用場景實現示例及優缺點(行為型模式——觀察者模式)

阿爾法的身體內部有一個智能芯片&#xff0c;這個芯片能夠根據環境和需求自動改變它的行為模式。當阿爾法需要完成不同任務時&#xff0c;它的內部狀態會發生變化&#xff0c;進而改變它的行為&#xff0c;就像是它變成了另一個機器人一樣。 一天&#xff0c;智能城的市長接到一…

多種方式實現 元素高度絲滑的從0-1顯示出來

選擇合適的方式&#xff0c;給用戶更好的體驗&#xff0c;多種方式實現 元素高度絲滑的從0-1顯示出來。 能用 CSS 實現的動畫&#xff0c;就不要采用 JS 去實現。 1、瀏覽器可以對CSS動畫進行優化&#xff0c;其優化原理類似于requestAnimationFrame&#xff0c;會把每一幀的…

java基礎學習:序列化之 - Fast serialization

在Java中&#xff0c;序列化是將對象的狀態轉換為字節流的過程&#xff0c;以便保存到文件、數據庫或通過網絡傳輸。Java標準庫提供了java.io.Serializable接口和相應的機制來進行序列化和反序列化。然而&#xff0c;標準的Java序列化機制性能較低&#xff0c;并且生成的字節流…

appium2.0 執行腳本遇到的問題

遇到的問題&#xff1a; appium 上的日志信息&#xff1a; 配置信息 方法一 之前用1.0的時候 地址默認加的 /wd/hub 在appium2.0上&#xff0c; 服務器默認路徑是 / 如果要用/wd/hub 需要通過啟動服務時設置基本路徑 appium --base-path/wd/hub 這樣就能正常執行了 方法二…

關于Kafka的17個問題

1.Kafka 的設計時什么樣的呢&#xff1f; Kafka 將消息以 topic 為單位進行歸納 將向 Kafka topic 發布消息的程序成為 producers. 將預訂 topics 并消費消息的程序成為 consumer. Kafka 以集群的方式運行&#xff0c;可以由一個或多個服務組成&#xff0c;每個服務叫做一個…

前端css常用筆記

文章目錄 一、樣式二、vue筆記2.1、組件之間的通信2.1.1 子組件調用父組件的方法2.1.2 父組件調用子組件的方法2.1.3 孫組件調用祖父組件方法的實現 2.2、使用若依時,node_nodules越來越大的問題2.3、echart筆記 一、樣式 1 文字與圖標對不齊的解決方法 /**給icon加上這個樣式即…

mysql的索引事務和存儲引擎

一、索引 1、索引 索引的概念 &#xff1a;索引是一個排序的列表&#xff0c;在列表當中存儲索引的值以及索引值對應數據所在的物理行。 索引的引用&#xff1a; 使用索引之后&#xff0c;就不需要掃描全表來定位某行的數據。 加快數據庫的查詢速度。 索引可以是表中的一…

ubuntu 網絡 通訊學習筆記2

1.ubuntu 網絡常用命令 在Ubuntu中&#xff0c;有許多網絡相關的常用命令。以下是一些主要命令及其用途&#xff1a; ifconfig&#xff1a;此命令用于顯示和配置網絡接口信息。你可以使用它來查看IP地址、子網掩碼、廣播地址等。 例如&#xff1a;ifconfig 注意&#xff1a…

在 K8s 上使用 KubeBlocks 提供的 MySQL operator 部署高可用 WordPress 站點

引言 WordPress WordPress 是全球最流行的內容管理系統&#xff08;CMS&#xff09;&#xff0c;自 2003 年發布以來&#xff0c;已成為網站建設的首選工具。其廣泛的插件和主題生態系統使用戶能夠輕松擴展功能和美化外觀。活躍的社區提供豐富的資源和支持&#xff0c;進一步…

[RK3588-Android12] 關于如何取消usb-typec的pd充電功能

問題描述 RK3588取消usb-typec的pd充電功能 解決方案&#xff1a; 在dts中fusb302節點下usb_con: connector子節點下添加如下熟悉&#xff1a; 打上如下2個補丁 diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index c8a4e57c9f9b..173f8cb7…