欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

在這里插入圖片描述

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

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

共同點(diǎn):

  • 都是C語(yǔ)言中用來(lái)進(jìn)行動(dòng)態(tài)內(nèi)存申請(qǐng)的庫(kù)函數(shù),申請(qǐng)的空間都在堆上,用完之后必須使用free來(lái)進(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來(lái)進(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語(yǔ)言中的動(dòng)態(tài)內(nèi)存管理方式在C++中仍然可以使用

原因:

1、C語(yǔ)言中的方式比較麻煩—需要用戶手動(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[]使用說(shuō)明
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語(yǔ)言中的malloc、calloc、realloc,但是并不能申請(qǐng)對(duì)象的空間
2、采用new/new[]---可以調(diào)用構(gòu)造函數(shù),注意:如果使用new[]申請(qǐng)連續(xù)的空間是,該類必須提供無(wú)參或全缺省的構(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來(lái)釋放空間

五、面試常問(wèn)問(wèn)題

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ì)開(kāi)辟空間,不會(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)存泄漏的危害:長(zhǎng)期運(yùn)行的程序出現(xiàn)內(nèi)存泄漏,影響很大,如操作系統(tǒng)、后臺(tái)服務(wù)等等,出現(xiàn)內(nèi)存泄漏會(huì)導(dǎo)致響應(yīng)越來(lái)越慢,最終卡死

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

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

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

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

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

指程序使用系統(tǒng)分配的資源,比方套接字、文件描述符、管道等沒(méi)有使用對(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ì)出問(wèn)題。需要下一條智能指針來(lái)管理才有保證。

2、 采用RAII思想或者智能指針來(lái)管理資源。

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

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

解決方案:

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

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

總結(jié)

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

相關(guān)文章

  • C++ LeetCode1781題解所有子字符串美麗值之和

    C++ LeetCode1781題解所有子字符串美麗值之和

    這篇文章主要為大家介紹了C++ LeetCode1781題解所有子字符串美麗值之和,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • C語(yǔ)言的字符空間與非字符空間你了解嗎

    C語(yǔ)言的字符空間與非字符空間你了解嗎

    這篇文章主要介紹了C語(yǔ)言的字符空間與非字符空間,本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下,希望能給你帶來(lái)幫助
    2021-08-08
  • C語(yǔ)言數(shù)據(jù)類型枚舉enum全面詳解示例教程

    C語(yǔ)言數(shù)據(jù)類型枚舉enum全面詳解示例教程

    生活中有很多地方會(huì)用到枚舉,比如一周有7天,可以一一枚舉;性別有男、女...等等都可以可以一一枚舉,今天來(lái)和筆者一起學(xué)習(xí)一下c語(yǔ)言枚舉吧
    2021-10-10
  • C++實(shí)現(xiàn)高校教室管理系統(tǒng)

    C++實(shí)現(xiàn)高校教室管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)高校教室管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 詳解C++中菱形繼承的原理與解決方法

    詳解C++中菱形繼承的原理與解決方法

    C++中的菱形繼承是多繼承的一種特殊情況,本文將通過(guò)海里帶大家了解一下菱形繼承形成的原因以及想應(yīng)的解決方法,感興趣的可以了解一下
    2023-02-02
  • Qt使用Matlab函數(shù)的詳細(xì)步驟

    Qt使用Matlab函數(shù)的詳細(xì)步驟

    由于項(xiàng)目需要,需要調(diào)用現(xiàn)有的matlab程序,下面這篇文章主要給大家介紹了關(guān)于Qt使用Matlab函數(shù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • C++實(shí)現(xiàn)LeetCode(23.合并k個(gè)有序鏈表)

    C++實(shí)現(xiàn)LeetCode(23.合并k個(gè)有序鏈表)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(23.合并k個(gè)有序鏈表),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C語(yǔ)言實(shí)現(xiàn)乒乓球比賽

    C語(yǔ)言實(shí)現(xiàn)乒乓球比賽

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)乒乓球比賽,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C++優(yōu)先隊(duì)列的使用小結(jié)

    C++優(yōu)先隊(duì)列的使用小結(jié)

    普通的隊(duì)列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),元素在隊(duì)列尾追加,而從隊(duì)列頭刪除,在優(yōu)先隊(duì)列中,元素被賦予優(yōu)先級(jí),本文主要介紹了C++優(yōu)先隊(duì)列的使用,感興趣的可以了解一下
    2023-11-11
  • C++實(shí)現(xiàn)停車場(chǎng)管理系統(tǒng)

    C++實(shí)現(xiàn)停車場(chǎng)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)停車場(chǎng)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評(píng)論