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

C++動態(tài)內存管理詳解

 更新時間:2021年08月18日 15:55:07   作者:久病成良醫(yī)  
今天小編就為大家分享一篇關于關于C++動態(tài)分配內存的介紹,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

1.C/C++程序地址空間

計算機物理內存的大小是固定的,在32位系統(tǒng)上,地址空間可達4G(2^32),這4G按照3:1的比例分配給用戶進程和內核。程序地址空間的構成:從上往下依次是:內核空間、棧區(qū)、共享區(qū)、堆區(qū)、未初始化數(shù)據(jù)區(qū)、初始化數(shù)據(jù)區(qū)、代碼區(qū)。而動態(tài)內存管理所申請的空間都是在堆區(qū),在堆區(qū)動態(tài)開辟的空間都需要我們手動去釋放它,否則會造成內存泄漏。

內核空間:操作系統(tǒng)相關代碼

棧區(qū):從高地址向低地址增長

共享區(qū):加載動態(tài)庫,共享內存

堆區(qū):從低地址向高地址增長

未初始化全局數(shù)據(jù)區(qū)

已初始化全局數(shù)據(jù)區(qū)

代碼區(qū):可執(zhí)行代碼及只讀常量

在這里插入圖片描述

2.C語言動態(tài)內存管理

(1)malloc

void* malloc(size_t size);

malloc()函數(shù)只有一個參數(shù),即要分配的內存空間的大小。

如果開辟成功,則返回一個指向開辟好空間的指針,如果開辟失敗,則返回一個空指針,因此每次申請完空間都需要判空。
malloc()函數(shù)返回值的類型是void*,在使用時需要自己強制轉換。

(2)calloc

void* calloc (size_t num, size_t size);

calloc()函數(shù)有兩個參數(shù),分別是元素的數(shù)目和每個元素的大小,這兩個參數(shù)的乘積就是要分配的內存空間的大小。
malloc申請后空間的值是隨機的,并沒有進行初始化,而calloc在申請后,對空間逐一進行初始化,并設置值為0;
calloc由于給每一個空間都要初始化,所以效率必然比malloc低。

(3)realloc

void* realloc (void* ptr, size_t size);

realloc()函數(shù)就實現(xiàn)對 動態(tài)開辟 內存大小的調整。

realloc()函數(shù)包含兩個參數(shù),分別是要調整的內存地址和調整的新大小。

realloc在調整內存空間時有兩種情況:

情況1:原有空間之后有足夠大的空間,我們就把需要擴展的內存直接放到原來空間的后面,原來空間的數(shù)據(jù)不發(fā)生變化。

情況2:原有空間之后沒有足夠大的空間,那就在堆上找一個合適大小的連續(xù)空間,將原來內存中的數(shù)據(jù)移動到新空間,然后將這個新空間的地址返回。

(4)free

void* free(void* ptr);

free函數(shù)用來釋放動態(tài)開辟的函數(shù)。

3.C++動態(tài)內存管理

(1)C++為什么要設計一套自己專屬的動態(tài)內存管理方式?

C++作為一門在C語言的基礎上發(fā)展而來的語言,它本身是完全兼容C語言的,也就是說,C語言的動態(tài)內存管理方式在C++中依舊可以正常使用。那它為什么還要設計一套屬于自己的動態(tài)內存管理方式呢?

在C++中,使用malloc/free申請或釋放內置類型的空間并沒有任何問題,但我們知道C++引入了類和對象的概念,而這一點帶來的影響就是并不能使用malloc從堆上為對象申請空間,因為malloc并不會去主動的去調用構造函數(shù),這意味著其并不能成為真正的對象。所以如果使用malloc只是申請了一段和對象同樣大小的空間而言,并非對象。同理使用free并不能釋放堆上對象的空間,因為free并不會調用析構函數(shù)去釋放對象中的資源。

而且C++所提供的動態(tài)內存管理方式使用起來更加方便、簡單,對用戶更加友好,并且不用去擔心空間可能會申請失敗的情況。

(2)new/delete定義

new操作符的格式:

new 類型;
new 類型(初值);
new 類型[];

delete操作符的格式:

delete 指針變量;
delete[] 指針變量;

1)new/delete操作內置類型

int main(){
	int *p1 = new int; //動態(tài)申請一個int類型的空間
	int *p2 = new int(10);  //動態(tài)申請一個int類型的空間并初始化為10
	int *p3 = new int[3];  //動態(tài)申請10個int類型的空間
	//釋放申請的空間
	delete p1;
	delete p2;
	delete[] p3;
	return 0;
}

2)new/delete操作自定義類型

//定義一個簡單的類
class Data{
public:
	//構造函數(shù)
	Data(int data = 0) : _data(data)
	{
		cout << "Data() :" << this << endl;
	}
	//析構函數(shù)
	~Data()
	{
		cout << "~Data() : " << this << endl;
	}
private:
	int _data;
};
int main()
{
	Data *d1 = new Data;  //申請單個Data類型的對象
	Data *d2 = new Data(10);  //申請單個Data類型的對象并初始化
	Data *d3 = new Data[5];  //申請5個Data類型的對象
	//依次釋放申請的對象資源
	delete d1;
	delete d2;
	delete[] d3;
	//使用new/delete為類對象申請或釋放空間時會主動調用構造函數(shù)/析構函數(shù)完成對象的構造/資源的清理。
	return 0;
}

(3)new/delete的實現(xiàn)原理

new 和 delete在堆上申請和釋放空間的時候,在底層實際上調用的是operator new和operator delete兩個全局函數(shù)。

而operator new和operator delete最終還是調用malloc和free來申請和釋放空間。

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

1)new/delete內置類型的原理

如果申請的是內置類型的空間,new和malloc,delete和free基本類似,不同的地方是:new/delete申請和釋放的是單個元素的空間,new[]和delete[]申請的是連續(xù)空間,而且new在申請空間失敗時會拋異常,malloc會返回NULL。也就是說使用new操作符不需要進行判空。

2)new/delete自定義類型的原理

new的原理

1.調用operator new函數(shù)申請空間

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

delete的原理

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

2.調用operator delete函數(shù)釋放對象的空間

new[]的原理

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

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

delete[]的原理
1.在釋放的對象空間上執(zhí)行N次析構函數(shù),完成N個對象中資源的清理

2.調用operator delete[]釋放空間,在operator delete[]中實際調用operator delete來釋放空間

4.malloc/free和new/delete的區(qū)別

共同點:

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

不同點:

1.malloc和free是函數(shù),new和delete是C++中的操作符

2.malloc申請的空間不會初始化,new可以初始化

3.malloc申請空間時,需要手動計算空間大小并傳遞,new只需在其后跟上類型即可

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

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

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

5.內存泄漏

內存泄漏是指你向系統(tǒng)申請分配內存進行使用(new/malloc),然后系統(tǒng)在堆內存中給這個對象申請一塊內存空間,但當我們使用完了卻沒有歸還給系統(tǒng)(delete),導致這個不使用的對象一直占據(jù)內存單元,造成系統(tǒng)將不能再把它分配給需要的程序。
一次內存泄漏的危害可以忽略不計,但是內存泄漏堆積則后果很嚴重,無論多少內存,遲早會被占完,造成內存泄漏。

總結

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

相關文章

  • C++實現(xiàn)字符串元音字母反轉的兩種方法

    C++實現(xiàn)字符串元音字母反轉的兩種方法

    在處理字符串問題時,我們經(jīng)常需要對其中的字符進行操作,例如反轉、替換等,本文將詳細討論如何在C++中實現(xiàn)僅反轉字符串中的所有元音字母,并返回結果字符串,需要的朋友可以參考下
    2024-07-07
  • C語言代碼實現(xiàn)2048游戲

    C語言代碼實現(xiàn)2048游戲

    這篇文章主要為大家詳細介紹了C語言代碼實現(xiàn)2048游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C/C++深入講解內存管理

    C/C++深入講解內存管理

    本章主要介紹C語言與C++的內存管理,以C++的內存分布作為引入,介紹C++不同于C語言的內存管理方式(new?delete對比?malloc?free),感興趣的朋友來看看吧
    2022-05-05
  • C++利用代理模式實現(xiàn)遠程代理,虛擬代理和保護代理

    C++利用代理模式實現(xiàn)遠程代理,虛擬代理和保護代理

    今天給大家簡單介紹代理模式,一個很簡單的設計模式,旨在不改變原對象的情況下通過代理對象來控制對原對象的訪問。代理模式根據(jù)具體情況還可以分為遠程代理、虛擬代理、保護代理等,下面來介紹一下
    2023-04-04
  • VS?Code?C++環(huán)境的搭建過程

    VS?Code?C++環(huán)境的搭建過程

    這篇文章主要介紹了VS?Code?C++環(huán)境的搭建,Somasegar 也告訴筆者這款編輯器也擁有對 Git 的開箱即用的支持,需要的朋友可以參考下
    2022-04-04
  • C語言中字符串和數(shù)字的相互轉換實現(xiàn)代碼

    C語言中字符串和數(shù)字的相互轉換實現(xiàn)代碼

    以下是對C語言中字符串和數(shù)字的相互轉換實現(xiàn)代碼進行了分析介紹,需要的朋友可以參考下
    2013-07-07
  • QT實現(xiàn)圖片輪播

    QT實現(xiàn)圖片輪播

    這篇文章主要介紹了QT實現(xiàn)圖片輪播,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • c++野指針的原理以及避免方法

    c++野指針的原理以及避免方法

    這篇文章主要介紹了c++野指針的原理以及避免方法,幫助大家更好的學習和理解c++,感興趣的朋友可以了解下
    2020-08-08
  • C語言三種方法解決輪轉數(shù)組問題

    C語言三種方法解決輪轉數(shù)組問題

    這篇文章主要給大家講解輪轉數(shù)組的問題,一個問題不局限于一種解法,希望你看了本文的解決方法以后可以舉一反三自己編寫,這樣你的技術水平會有質的提高
    2022-04-04
  • C++ Strassen算法代碼的實現(xiàn)

    C++ Strassen算法代碼的實現(xiàn)

    這篇文章主要介紹了C++ Strassen算法代碼的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03

最新評論