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

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

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

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

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

在這里插入圖片描述

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

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

共同點:

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

不同點:

  • malloc:返回值類型void*

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

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

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

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

  • calloc:返回值一致

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

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

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

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

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

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

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

大一點:返回原空間的首地址

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

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

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

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

原因:

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

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

在這里插入圖片描述

// C++中動態(tài)內(nèi)存管理方式:new/delete----申請單個類型的空間
// new[]/delete[]-----申請釋放一段連續(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)建了一個Test類型的對象,只是在堆上申請了一塊與Test類型大小相同的一塊空間
	//因為:malloc不調(diào)用構(gòu)造函數(shù)
	Test* p1 = (Test*)malloc(sizeof(Test));//malloc不會調(diào)用構(gòu)造函數(shù)
	if (nullptr == p1)
		return;
	//真正創(chuàng)建了一個對象,該對象的空間在堆上
	Test* p2 = new Test;//new在申請空間期間會調(diào)用構(gòu)造函數(shù)
	free(p1);//:在釋放空間期間,不會調(diào)用析構(gòu)函數(shù)
	delete p2;//:在釋放空間期間,會調(diào)用對象的析構(gòu)函數(shù)
}
/*
在C++中,如果想要在堆上申請空間:
1、采用C語言中的malloc、calloc、realloc,但是并不能申請對象的空間
2、采用new/new[]---可以調(diào)用構(gòu)造函數(shù),注意:如果使用new[]申請連續(xù)的空間是,該類必須提供無參或全缺省的構(gòu)造函數(shù)
3、malloc/free,new/delete,new[]/delete[]必須成對使用,否則會內(nèi)存泄漏或者代碼崩潰
*/

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

四、實現(xiàn)原理

new的原理

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

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

delete的原理

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

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

new T[N]的原理

1、調(diào)用operator new[]函數(shù),在operator new[]中實際調(diào)用operator new函數(shù)完成N個對象空間的申

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

delete[]的原理

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

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

五、面試常問問題

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

共同點是

都是從堆上申請空間,并且需要用戶手動釋放。

不同的地方是:

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

2、內(nèi)存泄漏

什么是內(nèi)存泄漏:內(nèi)存泄漏指因為疏忽或錯誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存的情況。內(nèi)存泄漏并不是指內(nèi)存在物理上的消失,而是應(yīng)用程序分配某段內(nèi)存后,因為設(shè)計錯誤,失去了對該段內(nèi)存的控制,因而造成了內(nèi)存的浪費(fèi)。

內(nèi)存泄漏的危害:長期運(yùn)行的程序出現(xiàn)內(nèi)存泄漏,影響很大,如操作系統(tǒng)、后臺服務(wù)等等,出現(xiàn)內(nèi)存泄漏會導(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è)計錯誤導(dǎo)致這部分內(nèi)存沒有被釋放,那么以后這部分空間將無法再被使用,就會產(chǎn)生Heap Leak。

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

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

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

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

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

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

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

解決方案:

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

2、事后查錯型。如泄漏檢測工具。

總結(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ì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • C++二叉樹實現(xiàn)詞頻分析功能

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

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

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

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

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

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

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

    這篇文章主要介紹了C++實現(xiàn)簡單的ls命令及其原理,C++實現(xiàn)ls命令可通過調(diào)用系統(tǒng)函數(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
  • 判斷一個數(shù)是不是素數(shù)的方法

    判斷一個數(shù)是不是素數(shù)的方法

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

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

    遞歸中遇到一個問題全排列的問題,我看見回溯特別神奇,特此記錄一下。對比一下深度優(yōu)先搜索與廣度優(yōu)先搜索,個人感覺這里的回溯像是一種遞歸樹中的深度優(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“的解決辦法,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12

最新評論

凌源市| 南雄市| 濮阳市| 桃江县| 青龙| 凤台县| 隆回县| 盐津县| 伊通| 南岸区| 天峻县| 安国市| 铁力市| 莒南县| 内江市| 宁南县| 米林县| 宜君县| 托里县| 左贡县| 建宁县| 东光县| 巫山县| 礼泉县| 漯河市| 盐亭县| 宣化县| 鲜城| 博湖县| 体育| 西宁市| 井陉县| 射洪县| 搜索| 乐业县| 太保市| 左云县| 平乐县| 珠海市| 安泽县| 芦山县|