欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:c語言 探索C嘎嘎:內(nèi)存管理

柚子快報邀請碼778899分享:c語言 探索C嘎嘎:內(nèi)存管理

http://yzkb.51969.com/

前言:

? 小編在前幾篇博客結(jié)束了類和對象的講解部分,各位讀者朋友一定要掌握這些內(nèi)容,因?yàn)轭惡蛯ο蟮闹R點(diǎn)是我們以后學(xué)習(xí)的基礎(chǔ),掌握好它我們以后學(xué)習(xí)起來才會變的輕松許多,廢話小編就不多說了,下面開始今天內(nèi)容的講解,代碼時間到。

目錄

1.C/C++的內(nèi)存分布

1.1.C/C++中程序區(qū)域內(nèi)存劃分

1.2.一個相關(guān)題目的講解

?2.C語言中內(nèi)存管理的方式

2.1.malloc函數(shù)

2.2.calloc函數(shù)

2.3.realloc函數(shù)

2.4.free函數(shù)

3.C++中內(nèi)存管理的方式

3.1.new操作符

3.1.1.單純動態(tài)內(nèi)存分配一個空間

3.1.2.分配一個空間并且初始化

3.1.3.想要分配很多空間

3.1.4.不僅想要分配很多空間,并且還想要初始化

3.2.delete操作符

1.釋放一個空間

2.釋放一塊空間

3.3.new/delete操作自定義類型

?3.3.1.malloc/free函數(shù)

?3.3.2.new/delete操作符

4.operator new與operator delete函數(shù)

5.new和delete的實(shí)現(xiàn)原理

5.1.內(nèi)置類型

5.2.自定義類型

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

正文:

1.C/C++的內(nèi)存分布

1.1.C/C++中程序區(qū)域內(nèi)存劃分

? 在進(jìn)行講解動態(tài)內(nèi)存管理之前,小編先給各位讀者朋友講述一下再C/C++中的程序區(qū)域內(nèi)存劃分,可能很多讀者朋友在學(xué)習(xí)C語言的時候就知道了這些內(nèi)存區(qū)域,但難免可能會忘掉一部分(就比如小編自己),所以小編先給讀者朋友科普一下區(qū)域內(nèi)存的劃分,如下圖所示:

? 為了讓各位讀者朋友了解的更加深刻一些,小編也給出了文字進(jìn)行補(bǔ)充說明:

? 1.棧又叫堆棧(和數(shù)據(jù)結(jié)構(gòu)的堆棧不同)——放置的有非靜態(tài)局部變量/函數(shù)參數(shù)/返回值等等,棧是向下增長的。

? 2.內(nèi)存映射段是高效的I/O映射方式,用于裝載一個共享的動態(tài)內(nèi)存庫。用戶可使用系統(tǒng)接口創(chuàng)建共享內(nèi)存,做進(jìn)程間通信。

? 3.堆用于程序運(yùn)行動態(tài)內(nèi)存分配,堆是可以向上增長的。

? 4.數(shù)據(jù)段:存儲全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù)。

? 5.代碼段:可執(zhí)行的代碼/只讀常量。

1.2.一個相關(guān)題目的講解

? 我們光知道上面那個知識點(diǎn),沒有實(shí)踐的話就有點(diǎn)紙上談兵的意思了,所以小編給各位讀者朋友出了一道題,來考驗(yàn)·一下自己對這部分的內(nèi)容是否掌握:

int a = 1;

static int b = 1;

void wang()

{

static int c = 1;

int d = 1;

int arr1[10] = { 1,2,3 };

char arr2[] = "abcd";

const char* pArr1 = "abcd";

int* pr1 = (int*)malloc(sizeof(int) * 4);

int* pr2 = (int*)calloc(4, sizeof(int));

int* pr3 = (int*)realloc(pr2,sizeof(int) * 4);

free(pr1);

free(pr3);

}

? 老規(guī)矩,讀者朋友先自己看一下這個題目,下面小編開始對這個題目進(jìn)行講解,首先,我們先看a的位置,此時a放在全局里面,所以一眼便是全局變量,全局變量都放在靜態(tài)區(qū)中,所以這個選C;之后在看b,雖然前面b是用static修飾過的,把它變成了靜態(tài)變量,但是b本身就是靜態(tài)變量,所以還是選擇C;之后在看c,c雖然放在函數(shù)體里面,但是它經(jīng)過了static修飾,已經(jīng)升級為靜態(tài)變量,所以此時c已經(jīng)在靜態(tài)區(qū)了,所以還是選C;之后在看d,此時d放在函數(shù)域里面,一般函數(shù)里面的變量都放置在棧中,所以選擇A;之后在看arr1,arr1是一個數(shù)組,但是本身還是在函數(shù)中,所以此時它還是建立在棧中,選A;我們在看arr2,arr2也是一個數(shù)組,只不過存放的是字符串常量,所以還是建立在棧中,選A;之后在往下看,此時是對arr2進(jìn)行解引用,解引用后取到的應(yīng)該是第一個字符a,還是存放在棧中,選A;之后我們繼續(xù)往下看,此時是pArr1依舊是一個數(shù)組,所以它還是在棧上建立的,選擇A;但是此時的解引用和上面就不一樣了,因?yàn)樗且粋€被const修飾過的數(shù)組,所以此時被解引用的對象具有常量性,所以應(yīng)該放在常量區(qū)中,所以此時這個選擇D;之后在看下面,pr2是一個被動態(tài)開辟出來的數(shù)組,但是還是一個數(shù)組本質(zhì)上,是在棧上建立的,選擇A;但是它解引用后的對象是動態(tài)開辟出來的,所以應(yīng)該放在堆上,選擇B。以上便就是這個題目的解題流程,各位讀者朋友一定要去好好的掌握這方面的知識,這對于我們以后的學(xué)習(xí)有很大的幫助,下面我們將要正式進(jìn)入動態(tài)內(nèi)存開辟的內(nèi)容!

?2.C語言中內(nèi)存管理的方式

? 在正式講述C++的動態(tài)內(nèi)存管理的方式之前,小編先帶各位讀者朋友回顧一下C語言階段我們曾學(xué)習(xí)過的動態(tài)內(nèi)存管理,這里小編先自我批評一下,我在C語言階段學(xué)習(xí)了很多的知識點(diǎn),但是因?yàn)槲以诖笠粫r候的懶惰,使得一些比較不錯的博客我沒有寫下去,其實(shí)就包括動態(tài)內(nèi)存管理,所以小編決定在C++的學(xué)習(xí)過程中,每學(xué)習(xí)完一個知識點(diǎn),都要生成一篇博客,以此來加強(qiáng)我的知識的的運(yùn)用能力,下面小編不多廢話,開始進(jìn)入各種動態(tài)函數(shù)講解環(huán)節(jié)

2.1.malloc函數(shù)

??

? 上圖便就是小編在一個網(wǎng)站上找到的malloc函數(shù)的講解,這里小編簡單講解一下,malloc函數(shù)的功能就是開辟出一塊void*的空間,括號里面放置的是你想開辟空間的大小,再看一眼返回值,返回值是void*,所以如果我們想開辟整形的空間,那就必須用到強(qiáng)制類型轉(zhuǎn)換了,即(類型),什么類型都可以,小到字節(jié),大到類都是可以開辟出來的,下面小編就拿·開辟四個大小為int的空間進(jìn)行舉例:

int* arr = (int*)malloc(sizeof(int) * 4);

? 上面便就是malloc函數(shù),不過經(jīng)過malloc函數(shù)動態(tài)開辟出來的變量,是不會進(jìn)行初始化操作的,下面小編就介紹一個不僅幫你開辟好,還幫你初始化的函數(shù):calloc。

2.2.calloc函數(shù)

? ?上圖是對于calloc函數(shù)的講解,它其實(shí)和malloc函數(shù)的功能是差不多的,只不過calloc函數(shù)比malloc函數(shù)多了會初始化動態(tài)內(nèi)存開辟的變量,它的使用方法也是蠻簡單的,上面的講解也說了,它和malloc函數(shù)是相同的返回值,所以此時我們還需要用到強(qiáng)制類型轉(zhuǎn)換,下面小編展示一下對于calloc使用的代碼:

int* arr1 = (int*)calloc(4, sizeof(int));

? 上面便就是這個函數(shù)的使用方法,calloc函數(shù)其實(shí)使用的頻率沒有上面的malloc函數(shù)以及接下來要將的calloc函數(shù)頻繁,但是各位讀者朋友也需要直到大致的用法,下面我們繼續(xù)進(jìn)入下一個函數(shù)的講解。

2.3.realloc函數(shù)

? ?這個函數(shù)相比各位讀者朋友都不陌生了,這個函數(shù)小編常常在數(shù)據(jù)結(jié)構(gòu)用,就比如擴(kuò)容操作就需要使用它,所以它的功能其實(shí)就是執(zhí)行擴(kuò)容操作的,當(dāng)我們動態(tài)開辟后的空間不夠用,那就可以接著擴(kuò)容,因?yàn)槭褂玫拇螖?shù)很頻繁,我就不多講了,下面小編就給各位展示一下代碼使用:

int* arr2 = (int*)realloc(arr1,sizeof(int) * 4);

2.4.free函數(shù)

? 最后,我們在使用完動態(tài)內(nèi)存分配的空間以后,我們還需要自己去進(jìn)行回收操作,不然可能會出現(xiàn)內(nèi)存泄露的問題,可能目前我們無法清楚內(nèi)存泄露的危害,但當(dāng)我們寫一個大型項(xiàng)目的時候,往往一個小的點(diǎn)就可能會使整個項(xiàng)目崩盤,所以作為程序員的我們,一定要培養(yǎng)好回收空間的好習(xí)慣,這里就需要用到free函數(shù),這個函數(shù)的使用方法很簡單,我們僅需在括號里放入我們想要釋放的空間即可,代碼如下所示:

free(arr);

free(arr1);

free(arr2);

arr = arr1 = arr2 = NULL; //釋放完空間一定要讓它們指向空,避免野指針的出現(xiàn)

? 以上便就是C語言中我們在動態(tài)內(nèi)存管理的時候常常使用到的函數(shù),各位讀者朋友要清楚它們的功能,在以后我們也是會使用到的,下面小編將要進(jìn)行C++階段動態(tài)內(nèi)存管理的方式。

3.C++中內(nèi)存管理的方式

? 講述完了C語言的內(nèi)存管理方式了,下面我們就要進(jìn)入C++的內(nèi)存管理了,這個才算是這篇文章的重點(diǎn),因?yàn)楫吘刮覀兡壳暗碾A段是C++而不是C語言了,不過C語言的函數(shù)C++還是可以正常使用的,但有些地方就有點(diǎn)無能為了,而且使用方法比較麻煩,于是C++推出了一套自己的內(nèi)存管理方式,下面進(jìn)入C++內(nèi)存管理方式的講解。

3.1.new操作符

? 請好好注意小編寫的這一個標(biāo)題,此時C++給我們提供了一個操作符,而不是一個函數(shù),這個操作符被命名為new,相較于C語言中動態(tài)內(nèi)存管理的函數(shù)這么多,C++僅憑一個new便可以實(shí)現(xiàn)動態(tài)內(nèi)存分配,這更好的體現(xiàn)了C++語言的簡潔美,廢話不多說,下面小編介紹一下new操作符的使用方式。

? 首先,new操作符可以分為四種操作方式,小編就用自己的語言敘述了,分別是:

3.1.1.單純動態(tài)內(nèi)存分配一個空間

? 正如標(biāo)題所言,new操作符可能會類似malloc函數(shù)一樣,僅僅開辟空間,我們也不初始化,僅需開辟一個空間(malloc函數(shù)是可以去控制個數(shù)的),這就是new操作符的基本使用,它用起來很簡單,左邊就是某一個類型的指針加名字,右邊就是new + 類型,如下面代碼所示:

int* p1 = new int;

float* p2 = new float;

char* p3 = new char;

3.1.2.分配一個空間并且初始化

? 這個操作是延續(xù)上面的操作來的,我們僅需在類型后面加個括號(),括號里面放置我們想要初始化的內(nèi)容即可,如下所示:

int* p1 = new int(1);

float* p2 = new float(1.2);

char* p3 = new char('a');

3.1.3.想要分配很多空間

? 這個操作也是延續(xù)第一個操作進(jìn)行的,此時我們僅需在類型后面加上[]即可,此時在[]里面放置我們想要設(shè)置的個數(shù)即可,如下所示:

int* p1 = new int[12];

float* p2 = new float[12];

char* p3 = new char[12];

3.1.4.不僅想要分配很多空間,并且還想要初始化

? 這個操作我們是延續(xù)3.1.3來的,此時我們僅需在[]后面加上{}即可,我們繼續(xù)在里面放置好我們想要的數(shù)即可,如果數(shù)多了,會直接在運(yùn)行的時候彈出警告,如果個數(shù)不夠,譬如整形,會自動把剩下的元素初始化為0,這就類似于我們給數(shù)組進(jìn)行初始化操作,下面給上代碼:

int* p1 = new int[12] {1,2,3,4,5,6,7,8};

float* p2 = new float[12] {1.1,1.2,1.3};

char* p3 = new char[12] {'a','b','c','d','e','f'};

? 以上便就是new操作符的使用,此時我們從這知道new操作符的用法還是蠻有趣的相較于C語言那幾個函數(shù),就比如這個我們可以自己初始化的操作,上面那仨除了第二個可以算是初始化,其他事做不到的,當(dāng)然對于內(nèi)置類型,其實(shí)兩者區(qū)別沒有很大,他們區(qū)別最大的還是類類型,等會各位讀者朋友就知道了,有開辟就有釋放,下面我們進(jìn)入下一個操作符的詳解。

3.2.delete操作符

? 當(dāng)然,C++中用于釋放開辟空間的也是一個操作符,它的名字我們也很熟悉,本身就有刪除的意思,對于delete操作符,同樣也有兩種使用方式,下面小編不多說廢話直接進(jìn)入講解使用環(huán)節(jié):

1.釋放一個空間

? 當(dāng)我們釋放一個空間的時候,我們繼續(xù)delete+開辟空間的名字即可,如下所示:

delete arr1;

2.釋放一塊空間

? 當(dāng)我們開辟很多空間的時候,此時我們僅需在delete后面加一個[],標(biāo)志著開辟了不少空間,然后加開辟空間的名字即可,如下所示:

delete[] arr1;

3.3.new/delete操作自定義類型

? 對于內(nèi)置類型,小編前面就說了,對于C語言和C++的動態(tài)內(nèi)存分配,在內(nèi)置類型差距不大,它們最大的差距就是在于類類型,類是C++一個特別重要的內(nèi)容,所以如果哪個對于類方便,哪一個就是最好用的,下面小編給出一段類的代碼,讓new,delete和malloc,free二者分別創(chuàng)建空間,看看他們的運(yùn)行情況:

?3.3.1.malloc/free函數(shù)

class wang

{

public:

wang()

{

_year = 12;

cout << "wang()" << endl;

}

~wang()

{

cout << "~wang" << endl;

}

private:

int _year;

};

int main()

{

wang* s1 = (wang*)malloc(sizeof(wang));

cout << "/" << endl;

free(s1);

cout << "/" << endl;

return 0;

}

? 下面我們看一下運(yùn)行結(jié)果:

? ?我們在對比一下new/delete是如何去完成這兩個函數(shù)的。

?3.3.2.new/delete操作符

class wang

{

public:

wang()

{

_year = 12;

cout << "wang()" << endl;

}

~wang()

{

cout << "~wang" << endl;

}

private:

int _year;

};

int main()

{

wang* s1 = new wang;

cout << "/" << endl;

delete s1;

cout << "/" << endl;

return 0;

}

? 下面來看一下它們的運(yùn)行結(jié)果:

? ?此刻C++的內(nèi)存管理和C語言的內(nèi)存管理對于類類型的變量差距就體現(xiàn)出來了,通過兩圖,我們可以清晰的看出,當(dāng)我們使用malloc/free函數(shù)的時候,這兩個函數(shù)真就僅僅的去開辟空間;當(dāng)我們使用new/delete操作符的時候,new操作符在被動態(tài)開辟出來后,自動幫我們?nèi)フ{(diào)用了構(gòu)造函數(shù),當(dāng)我們delete開辟好的空間以后,自動幫我們調(diào)用了析構(gòu)函數(shù),這邊就是它們在處理類類型對象的差距,此時我們通過運(yùn)行圖便可以知道我們以后到底去使用什么去進(jìn)行內(nèi)存管理,那當(dāng)然是——new和delete,這兩個操作符可以讓我們出錯的可能性小一點(diǎn),這就體現(xiàn)出了C++的嚴(yán)謹(jǐn)性。這便是我想告訴讀者朋友們的,當(dāng)然,我們不光要知道new/delete怎么用,還要去了解一下它們的底層是如何實(shí)現(xiàn)的,下面小編就簡單給大家講述一下兩個重要的函數(shù)。系好安全帶,出發(fā)嘍!

4.operator new與operator delete函數(shù)

? 可能很多讀者朋友看到標(biāo)題會很奇怪,這new和delete不是操作符嗎?怎么又蹦出來個這倆函數(shù),這倆函數(shù)和操作符又有什么聯(lián)系,不要著急,小編給各位讀者朋友認(rèn)真解釋的。首先,new和delete是用戶進(jìn)行動態(tài)內(nèi)存申請和釋放的操作符,而operator new和operator delete是系統(tǒng)提供的全局函數(shù),new在底層是通過調(diào)用operator new來實(shí)現(xiàn)開辟空間,delete在底層是通過調(diào)用operator delete來實(shí)現(xiàn)釋放空間,所以這兩個函數(shù)是屬于一個底層的函數(shù),均是為了實(shí)現(xiàn)操作符而生的,下面小編從代碼段中截取了它們的代碼供讀者朋友閱讀:

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

// 如果申請內(nèi)存失敗了,這里會拋出bad_alloc 類型異常

static const std::bad_alloc nomem;

_RAISE(nomem);

}

return (p);

} /

*

operator delete: 該函數(shù)最終是通過free來釋放空間的

* /

void operator delete(void* pUserData)

{

_CrtMemBlockHeader* pHead;

RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));

if (pUserData == NULL)

return;

_mlock(_HEAP_LOCK); /* block other threads */

__TRY

/* 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); /* release other threads */

__END_TRY_FINALLY

return;

} /

*

free的實(shí)現(xiàn)

* /

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

? 上面便就是operator new和operator delete的相關(guān)代碼,其中可能有很多讀者朋友會認(rèn)為根本讀不懂這段代碼,這是正常的,小編也是讀不懂,但是我們還能看到幾個熟悉的函數(shù),就比如malloc,free函數(shù),從而我們可以知道operator new其實(shí)也是用malloc函數(shù)來進(jìn)行申請空間的,如果申請成功直接就返回了,否則執(zhí)行用戶提供的空間不足應(yīng)對措施,如果用戶提供該措施就繼續(xù)申請,否則就拋異常。(異常這個概念小編以后會說,但是不是現(xiàn)在,現(xiàn)在小編也不清楚這個,但是以后小編學(xué)習(xí)完以后一定會回來進(jìn)行補(bǔ)充說明的)。而operator delete的底層則是free實(shí)現(xiàn)的,各位讀者朋友要知道這些事情,一日積累一點(diǎn),日積月累,我們就可以成為一個非常強(qiáng)大的程序員,下面我們進(jìn)入下一部分的講解!

5.new和delete的實(shí)現(xiàn)原理

5.1.內(nèi)置類型

? 如果申請的是內(nèi)置類型的空間,new和malloc,free和delete基本上是類似的,但是不同的地方是:new/delete申請和釋放的是單個元素的空間,new[]和delete[]申請的是一塊連續(xù)的空間,并且如果new失敗了是會拋異常的,malloc失敗會傳NULL。但是小編還是推薦各位讀者朋友使用new和delete,畢竟我們學(xué)的是C++,所以函數(shù)最好也是C++的。

5.2.自定義類型

●new的原理

? 1.調(diào)用operator new函數(shù)申請空間。2.在申請空間的同時調(diào)用構(gòu)造函數(shù),完成對象的構(gòu)造。

●delete的原理

? 1.調(diào)用operator delete函數(shù)釋放空間。2.在釋放空間的同時調(diào)用析構(gòu)函數(shù),完成對象的析構(gòu)。

●new[T]的原理

? 1.調(diào)用operator new[]函數(shù)申請空間,而operator new[]實(shí)則是調(diào)用了T次operator new來進(jìn)行申請空間。2.在申請的空間調(diào)用了T次構(gòu)造函數(shù)

●delete[T]的原理

? 1.調(diào)用了operator delete[]函數(shù)釋放空間。2.在釋放空間的過程中調(diào)用了T次析構(gòu)函數(shù)。

? 以上便就是這兩個操作符的實(shí)現(xiàn)原理,各位了解就可以,重點(diǎn)是知道如何使用以及它們的底層是如何去實(shí)現(xiàn)的。

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

? 其實(shí)區(qū)別小編在前面就多次提到了,但是我還是系統(tǒng)性的總結(jié)一下這倆的區(qū)別吧。

??malloc/free和new/delete的共同點(diǎn)都是從堆上去建立空間,并且都需要自己去手動釋放空間,不然有內(nèi)存泄露的風(fēng)險,但有以下的不同點(diǎn):

? 1.malloc和free是倆函數(shù),new/delete是倆操作符。

? 2.malloc申請的空間不會初始化,new是可以進(jìn)行初始化操作的(上面講過)。

? 3.malloc申請空間時,需要自己手動計算一下要開辟空間的大小并傳遞,new只需在后面加上空間的類型即可,如果想要申請多個的話,直接[]里面加上個數(shù)即可,灰常的方便~

? 4.malloc的返回值是void*,在使用的時候一定要強(qiáng)轉(zhuǎn),new不需要,因?yàn)閚ew后面會跟上開辟空間的類型。

? 5.malloc申請空間失敗的時候,會返回空,所以必須去判空,而new申請空間失敗,不要判空,只需自己去捕獲異常即可。

? 6.申請自定義類型的時候,malloc/free只會開辟空間,不會調(diào)用析構(gòu)函數(shù)和構(gòu)造函數(shù),而new在申請空間的時候會自動調(diào)用構(gòu)造函數(shù)完成初始化,在delete銷毀的時候自動調(diào)用析構(gòu)函數(shù)去析構(gòu)對象,完成空間中資源的清理。

? 以上便就是區(qū)別,各位讀者朋友要牢記~

7.總結(jié)

? 以上便就是今天小編要講述的內(nèi)容,各位讀者朋友一定要知道C++是如何進(jìn)行內(nèi)存分配的,明白new和delete的用法,小編其實(shí)還有一個點(diǎn)沒講,那就是定位new,但我感覺這部分不太重要,最主要的是我都不太明白,我就不自己嘗試講去禍害別人了,如果文章有錯誤,請在評論區(qū)指出,我定會及時的回復(fù),那么,我們下一篇文章見啦!

柚子快報邀請碼778899分享:c語言 探索C嘎嘎:內(nèi)存管理

http://yzkb.51969.com/

推薦鏈接

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19570125.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄