最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++的內(nèi)存管理詳細(xì)解釋

 更新時(shí)間:2021年09月23日 14:42:01   作者:An_Mo  
這篇文章主要介紹了C/C++中的內(nèi)存管理小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、C/C++內(nèi)存分布

  • 棧又叫堆棧,非靜態(tài)局部變量/函數(shù)參數(shù)/返回值等等,棧是向下增長的。
  • 內(nèi)存映射段是高效的I/O映射方式,用于裝載一個(gè)共享的動(dòng)態(tài)內(nèi)存庫。用戶可使用系統(tǒng)接口創(chuàng)建共享共享內(nèi)存,做進(jìn)程間通信。
  • 堆用于程序運(yùn)行時(shí)動(dòng)態(tài)內(nèi)存分配,堆是可以向上增長的。
  • 數(shù)據(jù)段–存儲(chǔ)全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù)。
  • 代碼段–可執(zhí)行的代碼/只讀常量。

在這里插入圖片描述

二、C語言中動(dòng)態(tài)內(nèi)存管理方式:

1、malloc/calloc/realloc區(qū)別:

共同點(diǎn):

  • 都是C語言中用來進(jìn)行動(dòng)態(tài)內(nèi)存申請(qǐng)的庫函數(shù),申請(qǐng)的空間都在堆上,用完之后必須使用free來進(jìn)行釋放
  • 返回值類型都是void*在接受返回的地址時(shí)必須要進(jìn)行強(qiáng)轉(zhuǎn)
  • 如果申請(qǐng)空間成功:返回的是空間的首地址,如果失敗返回的是NULL

不同點(diǎn):

  • malloc:返回值類型void*

在接受返回的空間地址時(shí)必須要進(jìn)行強(qiáng)轉(zhuǎn)

成功:空間首地址 失敗:NULL

參數(shù):申請(qǐng)的空間所占總的字節(jié)數(shù)

申請(qǐng)的空間在堆上,使用完成后必須要使用free來進(jìn)行釋放

  • calloc:返回值一致

參數(shù)列表:參數(shù)一表示元素的個(gè)數(shù);參數(shù)二表示單個(gè)類型的字節(jié)數(shù)

功能:與malloc基本相同,但是calloc會(huì)對(duì)其申請(qǐng)的空間進(jìn)行初始化

  • realloc(void* p, size_t size):將p所指向空間的大小調(diào)整到size字節(jié)

p指向的是NULL:該函數(shù)的類似malloc

假設(shè):p所指向的空間總共占o(jì)ld個(gè)字節(jié)

size <= old:將p所指向的空間縮小到size個(gè)字節(jié)---->直接返回值p所指向空間的首地址

size > old:將p所指向的空間擴(kuò)增到size個(gè)字節(jié)

大一點(diǎn):返回原空間的首地址

大的多的多:申請(qǐng)新空間;將舊空間中元素拷貝到新空間;釋放舊空間;返回新空間的首地址

三、C++中動(dòng)態(tài)內(nèi)存管理:new/delete

C++為什么要搞一套動(dòng)態(tài)內(nèi)存管理?

首先:C語言中的動(dòng)態(tài)內(nèi)存管理方式在C++中仍然可以使用

原因:

1、C語言中的方式比較麻煩—需要用戶手動(dòng)算字節(jié)數(shù),需要對(duì)返回結(jié)果強(qiáng)轉(zhuǎn),需要判空,需要包含頭文件

2、malloc、free:不會(huì)調(diào)用構(gòu)造函數(shù)/析構(gòu)函數(shù);new、delete:在進(jìn)行空間申請(qǐng)和釋放時(shí)是會(huì)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)的

在這里插入圖片描述

// C++中動(dòng)態(tài)內(nèi)存管理方式:new/delete----申請(qǐng)單個(gè)類型的空間
// new[]/delete[]-----申請(qǐng)釋放一段連續(xù)的空間
//注意:1、new/delete不是函數(shù),是C++中的關(guān)鍵字||操作符
//		2、new的空間必須要有delete釋放  new[]必須使用delete[]釋放
class Test
{
public:
	Test()
		:_t(10)
	{
		cout << "Test():" << this << endl;
	}
	~Test()
	{
		cout << "~Test():" << this << endl;
	}
	int _t;
};
//new/delete和new[]/delete[]使用說明
void Test1()
{
	int* p1 = new int;
	int* p2 = new int(100);
	int* p3 = new int[10];
	int* p4 = new int[10]{ 1,2,3,4,5,6,7,8,9,0 };
	delete p1;
	delete p2;
	delete[] p3;
	delete[] p4;
}
void Test2()
{
	//malloc并不是創(chuàng)建了一個(gè)Test類型的對(duì)象,只是在堆上申請(qǐng)了一塊與Test類型大小相同的一塊空間
	//因?yàn)椋簃alloc不調(diào)用構(gòu)造函數(shù)
	Test* p1 = (Test*)malloc(sizeof(Test));//malloc不會(huì)調(diào)用構(gòu)造函數(shù)
	if (nullptr == p1)
		return;
	//真正創(chuàng)建了一個(gè)對(duì)象,該對(duì)象的空間在堆上
	Test* p2 = new Test;//new在申請(qǐng)空間期間會(huì)調(diào)用構(gòu)造函數(shù)
	free(p1);//:在釋放空間期間,不會(huì)調(diào)用析構(gòu)函數(shù)
	delete p2;//:在釋放空間期間,會(huì)調(diào)用對(duì)象的析構(gòu)函數(shù)
}
/*
在C++中,如果想要在堆上申請(qǐng)空間:
1、采用C語言中的malloc、calloc、realloc,但是并不能申請(qǐng)對(duì)象的空間
2、采用new/new[]---可以調(diào)用構(gòu)造函數(shù),注意:如果使用new[]申請(qǐng)連續(xù)的空間是,該類必須提供無參或全缺省的構(gòu)造函數(shù)
3、malloc/free,new/delete,new[]/delete[]必須成對(duì)使用,否則會(huì)內(nèi)存泄漏或者代碼崩潰
*/

注意:申請(qǐng)和釋放單個(gè)元素的空間,使用new和delete操作符,申請(qǐng)和釋放連續(xù)的空間,使用new[]和delete[]

四、實(shí)現(xiàn)原理

new的原理

1、調(diào)用operator new函數(shù)申請(qǐng)空間

2、在申請(qǐng)的空間上執(zhí)行構(gòu)造函數(shù),完成對(duì)象的構(gòu)造

delete的原理

1、在空間上執(zhí)行析構(gòu)函數(shù),完成對(duì)象中資源的清理工作

2、 調(diào)用operator delete函數(shù)釋放對(duì)象的空間

new T[N]的原理

1、調(diào)用operator new[]函數(shù),在operator new[]中實(shí)際調(diào)用operator new函數(shù)完成N個(gè)對(duì)象空間的申
請(qǐng)

2、在申請(qǐng)的空間上執(zhí)行N次構(gòu)造函數(shù)

delete[]的原理

1、 在釋放的對(duì)象空間上執(zhí)行N次析構(gòu)函數(shù),完成N個(gè)對(duì)象中資源的清理

2、調(diào)用operator delete[]釋放空間,實(shí)際在operator delete[]中調(diào)用operator delete來釋放空間

五、面試常問問題

1、malloc/free和new/delete的區(qū)別

共同點(diǎn)是

都是從堆上申請(qǐng)空間,并且需要用戶手動(dòng)釋放。

不同的地方是:

  • malloc和free是函數(shù),new和delete是操作符
  • malloc申請(qǐng)的空間不會(huì)初始化,new可以初始化
  • malloc申請(qǐng)空間時(shí),需要手動(dòng)計(jì)算空間大小并傳遞,new只需在其后跟上空間的類型即可
  • malloc的返回值為void*, 在使用時(shí)必須強(qiáng)轉(zhuǎn),new不需要,因?yàn)閚ew后跟的是空間的類型
  • malloc申請(qǐng)空間失敗時(shí),返回的是NULL,因此使用時(shí)必須判空,new不需要,但是new需要捕獲異常
  • 申請(qǐng)自定義類型對(duì)象時(shí),malloc/free只會(huì)開辟空間,不會(huì)調(diào)用構(gòu)造函數(shù)與析構(gòu)函數(shù),而new在申請(qǐng)空間后會(huì)調(diào)用構(gòu)造函數(shù)完成對(duì)象的初始化,delete在釋放空間前會(huì)調(diào)用析構(gòu)函數(shù)完成空間中資源的清理

2、內(nèi)存泄漏

什么是內(nèi)存泄漏:內(nèi)存泄漏指因?yàn)槭韬龌蝈e(cuò)誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存的情況。內(nèi)存泄漏并不是指內(nèi)存在物理上的消失,而是應(yīng)用程序分配某段內(nèi)存后,因?yàn)樵O(shè)計(jì)錯(cuò)誤,失去了對(duì)該段內(nèi)存的控制,因而造成了內(nèi)存的浪費(fèi)。

內(nèi)存泄漏的危害:長期運(yùn)行的程序出現(xiàn)內(nèi)存泄漏,影響很大,如操作系統(tǒng)、后臺(tái)服務(wù)等等,出現(xiàn)內(nèi)存泄漏會(huì)導(dǎo)致響應(yīng)越來越慢,最終卡死

內(nèi)存泄漏分類(了解)

C/C++程序中一般我們關(guān)心兩種方面的內(nèi)存泄漏:

1、堆內(nèi)存泄漏(Heap leak)

堆內(nèi)存指的是程序執(zhí)行中依據(jù)須要分配通過malloc / calloc / realloc / new等從堆中分配的一塊內(nèi)存,用完后必須通過調(diào)用相應(yīng)的 free或者delete 刪掉。假設(shè)程序的設(shè)計(jì)錯(cuò)誤導(dǎo)致這部分內(nèi)存沒有被釋放,那么以后這部分空間將無法再被使用,就會(huì)產(chǎn)生Heap Leak。

2、系統(tǒng)資源泄漏

指程序使用系統(tǒng)分配的資源,比方套接字、文件描述符、管道等沒有使用對(duì)應(yīng)的函數(shù)釋放掉,導(dǎo)致系統(tǒng)資源的浪費(fèi),嚴(yán)重可導(dǎo)致系統(tǒng)效能減少,系統(tǒng)執(zhí)行不穩(wěn)定。

如何避免內(nèi)存泄漏

1、工程前期良好的設(shè)計(jì)規(guī)范,養(yǎng)成良好的編碼規(guī)范,申請(qǐng)的內(nèi)存空間記著匹配的去釋放。ps:這個(gè)理想狀態(tài)。但是如果碰上異常時(shí),就算注意釋放了,還是可能會(huì)出問題。需要下一條智能指針來管理才有保證。

2、 采用RAII思想或者智能指針來管理資源。

3、有些公司內(nèi)部規(guī)范使用內(nèi)部實(shí)現(xiàn)的私有內(nèi)存管理庫。這套庫自帶內(nèi)存泄漏檢測(cè)的功能選項(xiàng)。

4、出問題了使用內(nèi)存泄漏工具檢測(cè)。ps:不過很多工具都不夠靠譜,或者收費(fèi)昂貴。

解決方案:

1、事前預(yù)防型。如智能指針等。

2、事后查錯(cuò)型。如泄漏檢測(cè)工具。

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • C語言中花式退出程序的方式總結(jié)

    C語言中花式退出程序的方式總結(jié)

    在本篇文章當(dāng)中主要給大家介紹C語言當(dāng)中一些不常用的特性,比如在main函數(shù)之前和之后設(shè)置我們想要執(zhí)行的函數(shù),以及各種花式退出程序的方式,需要的可以參考一下
    2022-10-10
  • 基于VS2019配置opencv4.0的方法步驟

    基于VS2019配置opencv4.0的方法步驟

    這篇文章主要介紹了基于VS2019配置opencv4.0的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • C++二叉樹實(shí)現(xiàn)詞頻分析功能

    C++二叉樹實(shí)現(xiàn)詞頻分析功能

    這篇文章主要為大家詳細(xì)介紹了C++二叉樹實(shí)現(xiàn)詞頻分析功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • C++、python和go語言實(shí)現(xiàn)的簡單客戶端服務(wù)器代碼示例

    C++、python和go語言實(shí)現(xiàn)的簡單客戶端服務(wù)器代碼示例

    這篇文章主要介紹了C++、python和go語言實(shí)現(xiàn)的簡單客戶端服務(wù)器代碼示例,本文分別給出了3種語言的客戶端服務(wù)器通信代碼實(shí)例,需要的朋友可以參考下
    2015-03-03
  • C++實(shí)現(xiàn)LeetCode(18.四數(shù)之和)

    C++實(shí)現(xiàn)LeetCode(18.四數(shù)之和)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(18.四數(shù)之和),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++實(shí)現(xiàn)簡單的ls命令及其原理

    C++實(shí)現(xiàn)簡單的ls命令及其原理

    這篇文章主要介紹了C++實(shí)現(xiàn)簡單的ls命令及其原理,C++實(shí)現(xiàn)ls命令可通過調(diào)用系統(tǒng)函數(shù)實(shí)現(xiàn)讀取目錄中的文件名和屬性,再通過標(biāo)準(zhǔn)輸出進(jìn)行顯示,需要的朋友可以參考下
    2023-05-05
  • C語言中scanf的用法舉例

    C語言中scanf的用法舉例

    本節(jié)介紹輸入函數(shù)?scanf?的用法,scanf?和?printf?一樣,非常重要,而且用得非常多,所以一定要掌握,這篇文章主要介紹了C++中scanf的用法舉例,需要的朋友可以參考下
    2022-11-11
  • 判斷一個(gè)數(shù)是不是素?cái)?shù)的方法

    判斷一個(gè)數(shù)是不是素?cái)?shù)的方法

    判斷一個(gè)數(shù)是不是素?cái)?shù)的方法,需要的朋友可以參考一下
    2013-03-03
  • C++回溯算法中的全排列問題分析探討

    C++回溯算法中的全排列問題分析探討

    遞歸中遇到一個(gè)問題全排列的問題,我看見回溯特別神奇,特此記錄一下。對(duì)比一下深度優(yōu)先搜索與廣度優(yōu)先搜索,個(gè)人感覺這里的回溯像是一種遞歸樹中的深度優(yōu)先搜索的算法,他不斷構(gòu)造往下延伸的深度,使其達(dá)到完全編列
    2023-03-03
  • VS2017開發(fā)C語言出現(xiàn)“no_init_all“的解決辦法

    VS2017開發(fā)C語言出現(xiàn)“no_init_all“的解決辦法

    這篇文章介紹了VS2017開發(fā)C語言出現(xiàn)“no_init_all“的解決辦法,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12

最新評(píng)論

墨玉县| 定远县| 罗源县| 井陉县| 辉南县| 缙云县| 当涂县| 连城县| 鲁山县| 安远县| 兴隆县| 永胜县| 沈丘县| 乐清市| 汽车| 乌什县| 古蔺县| 永川市| 沅陵县| 固始县| 庐江县| 乌兰察布市| 盐源县| 枣阳市| 白沙| 油尖旺区| 青阳县| 新宾| 西林县| 嵊州市| 裕民县| 会东县| 林甸县| 昌吉市| 长寿区| 辽宁省| 皮山县| 赣榆县| 迁西县| 沂水县| 文化|