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

C++內(nèi)存分布及用法

 更新時間:2022年01月24日 16:50:09   作者:一個熱愛學(xué)習(xí)的深度渣渣  
這篇文章主要介紹了C++內(nèi)存分布及用法,從內(nèi)存的基礎(chǔ)概念到內(nèi)存分配進(jìn)行了講解,內(nèi)存是我們開發(fā)中最重要的一部分,往往邏輯上的錯誤就會造成內(nèi)存泄漏,導(dǎo)致程序無法運(yùn)行,下面我們就來了解文章對該內(nèi)容的詳細(xì)介紹

一、內(nèi)存基礎(chǔ)

1、內(nèi)存分布

通過下面一張圖看看C++的內(nèi)存分布:

棧區(qū):由編譯器自動分配與釋放,存放為程序運(yùn)行時函數(shù)分配的局部變量、函數(shù)參數(shù);棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配內(nèi)存的容量有限;

堆區(qū):由new、malloc分配的內(nèi)存塊,釋放由應(yīng)用程序控制,不需要編譯器釋放;如果程序員沒有對該內(nèi)存進(jìn)行釋放,程序結(jié)束后系統(tǒng)自動回收,堆的地方比棧大很多;

靜態(tài)區(qū):存放的是static的靜態(tài)變量和一些全局變量,特點(diǎn)是只讀、大小固定;靜態(tài)變量和全局變量的存儲期是一起的,一旦靜態(tài)區(qū)的內(nèi)存被分配,要一直等到程序全部結(jié)束后才釋放;

2、棧區(qū)與堆區(qū)的區(qū)別

1、分配方式不同:棧區(qū)系統(tǒng)分配系統(tǒng)回收;堆區(qū)由程序員手動申請,需要求程序員自行回收,如果沒有回收,系統(tǒng)在程序結(jié)束后會進(jìn)行回收,這種情況會造成內(nèi)存泄漏;

2、生命周期不同:棧區(qū)生命周期是系統(tǒng)分配到系統(tǒng)回收,也就是在大括號內(nèi);堆區(qū)是從申請到釋放;

3、效率不同:主要原因是地址空間是否連續(xù),棧區(qū)地址空間是連續(xù)的,效率會高一些;堆區(qū)地址空間不連續(xù),需要遍歷鏈表才能找到最近的地址,效率會低一些;

4、內(nèi)存碎片:堆區(qū)容易產(chǎn)生內(nèi)存碎片,棧區(qū)不會;

5、生長方向不同:棧區(qū)申請空間的地址(表示地址的八個十六進(jìn)制數(shù))是從大到小的,堆區(qū)申請空間地址是從小到大的。棧區(qū)是先進(jìn)后出的原則,類比棧結(jié)構(gòu)的特點(diǎn);

  • 棧區(qū)特點(diǎn):更好的局部性,對象自動銷毀;
  • 堆區(qū)特點(diǎn):運(yùn)行期動態(tài)擴(kuò)展,需要顯示釋放;

注意點(diǎn):申請的空間是在堆區(qū),變量本身是在棧區(qū)!

二、內(nèi)存分配

1、內(nèi)存分配方式

可操作的內(nèi)存分配:

  • 靜態(tài)存儲區(qū)分配:static靜態(tài)變量、全局變量;
  • 棧上分配:局部變量;
  • 堆上分配:new、malloc進(jìn)行內(nèi)存分配;

不可操作的內(nèi)存分配:

內(nèi)核區(qū)、代碼區(qū)、局部變量的分配也屬于系統(tǒng)分配;

2、new的用法

C++中通常使用new、delete來構(gòu)造和銷毀對象;

使用new創(chuàng)建對象,返回的是對象的首地址,需要用指針接收:

int *y = new int(2);
std::cout << *y << std::endl;

對象的構(gòu)建和銷毀分為兩步:分配內(nèi)存、所分配內(nèi)存上構(gòu)造對象(銷毀與之類似);

new的幾種常見形式:

  • new int(2) :構(gòu)造單一對象、new int[5]:構(gòu)造數(shù)組;
  • nothrow new:標(biāo)準(zhǔn)庫定義,解決內(nèi)存分配失敗異常的問題;
  • placement new:使用已經(jīng)創(chuàng)建的內(nèi)存,跳過分配內(nèi)存;
  • new auto

3、delete用法

根據(jù)分配的是單一對象還是數(shù)組,采用相應(yīng)的方式銷毀;

int *y = new int[3];
delete[] y;

不能delete一個非new返回的內(nèi)存(也就是棧內(nèi)存);
delete nullptr是可被允許的;
同一塊內(nèi)存不能delete多次;

4、new與malloc的區(qū)別

  new不需要指定分配多大,malloc使用的時候必須指定大??;new的底層實(shí)現(xiàn)就是malloc,兩者都必須釋放內(nèi)存,不否則容易造成野指針或內(nèi)存泄漏。需要注意一點(diǎn),釋放內(nèi)存后需設(shè)置相關(guān)指針為空指針;

總結(jié):

  • 屬性:new為關(guān)鍵字(編譯器),malloc是庫函數(shù)(需引入頭文件);
  • 參數(shù):new無需指定大小,malloc需指定大??;
  • 返回類型:new返回對象指針,malloc返回void*;
  • 對于自定義的類:new會調(diào)用構(gòu)造和析構(gòu)函數(shù),malloc不會調(diào)用構(gòu)造和析構(gòu)函數(shù);
  • 分配失?。?/strong>new會拋出異常,malloc會返回空;

5、內(nèi)存泄漏

是指由于疏忽或錯誤造成程序未能釋放掉不再使用的內(nèi)存的情況,內(nèi)存泄漏并非指內(nèi)存在物理上的小時,而是應(yīng)用程序分配某段內(nèi)存后,由于設(shè)計(jì)錯誤,失去該段內(nèi)存的控制從而造成內(nèi)存浪費(fèi);

可能的原因:

  • 1、申請后未釋放(最常見)
  • 2、void* 指針的釋放
  • 3、new[] 回收時沒有用delete[] ,數(shù)組的回收要注意

三、內(nèi)存拓展

1、內(nèi)存概念

  計(jì)算機(jī)重要部件之一,是外存與CPU進(jìn)行溝通的橋梁。計(jì)算機(jī)所有程序都是在內(nèi)存運(yùn)行的,因此內(nèi)存的性能對計(jì)算機(jī)的影響非常大。內(nèi)存也稱為內(nèi)存儲器和主存儲器,作用是暫時存放CPU的運(yùn)算數(shù)據(jù),以及與硬盤等外部存儲器交換的數(shù)據(jù);

尋址空間:保存內(nèi)存地址的多少,通常我們說的4G內(nèi)存,就表示計(jì)算機(jī)能保存2的32次方個地址,也就是能找到這些地址上的二進(jìn)制信息;

尋址能力:每個地址里能存多少個bit,現(xiàn)在的計(jì)算機(jī)大多數(shù)是16位機(jī)器了;

2、虛擬內(nèi)存

使得系統(tǒng)運(yùn)行實(shí)際的內(nèi)存空間比想象的大得多,虛擬內(nèi)存是可以遠(yuǎn)大于物理內(nèi)存的,同時主要為了使程序運(yùn)行的時候可以不限制于只訪問內(nèi)存大小,可以通過虛擬內(nèi)存地址去訪問磁盤空間;

每一個進(jìn)程虛擬內(nèi)存都是獨(dú)立的,獨(dú)立的享有計(jì)算機(jī)的內(nèi)存。虛擬內(nèi)存地址的大小是與地址總線位數(shù)相關(guān),物理內(nèi)存地址的大小是與物理內(nèi)存條的容量與磁盤容量相關(guān)。

四、思考

1、代碼中的b屬于棧區(qū)還是堆區(qū)?

void fun()
{
 int *b = new int[14];
}

b是在棧區(qū)的變量,由于b是一個局部變量,隨著函數(shù)域 的結(jié)束被釋放,不需要程序員自行釋放,盡管b使用new進(jìn)行初始化,還是可以認(rèn)為分配在棧區(qū);

總結(jié):

本次系統(tǒng)的從內(nèi)存的基礎(chǔ)概念到內(nèi)存分配進(jìn)行了講解,內(nèi)存是我們開發(fā)中最重要的一部分,往往邏輯上的錯誤就會造成內(nèi)存泄漏,導(dǎo)致程序無法運(yùn)行。或者一些分配內(nèi)存的方式不夠細(xì)心,也會造成冗余內(nèi)存的使用。在目前的很多嵌入式板子上,針對內(nèi)存的接口是必備的,往往也都是基于malloc修改;
還有一點(diǎn)需要注意,不管任何機(jī)器上運(yùn)行程序,操作的都是虛擬內(nèi)存,內(nèi)部通過頁表定位到對應(yīng)的物理內(nèi)存。關(guān)于硬件方面的本質(zhì),如果做嵌入式端的話需要深入研究。

到此這篇關(guān)于C++內(nèi)存分布及用法的文章就介紹到這了,更多相關(guān)C++內(nèi)存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言內(nèi)存泄漏常見情況及解決方案詳解

    C語言內(nèi)存泄漏常見情況及解決方案詳解

    這篇文章主要為大家介紹了C語言內(nèi)存泄漏常見情況及解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • C++開發(fā)的Redis數(shù)據(jù)導(dǎo)入工具優(yōu)化

    C++開發(fā)的Redis數(shù)據(jù)導(dǎo)入工具優(yōu)化

    這篇文章主要介紹了C++開發(fā)的Redis數(shù)據(jù)導(dǎo)入工具優(yōu)化方法的相關(guān)資料,需要的朋友可以參考下
    2015-07-07
  • C語言pow()函數(shù)實(shí)現(xiàn)求x的y次方的值

    C語言pow()函數(shù)實(shí)現(xiàn)求x的y次方的值

    這篇文章主要介紹了C語言pow()函數(shù)實(shí)現(xiàn)求x的y次方的值,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 深入分析C++中幾個最不常用的關(guān)鍵字

    深入分析C++中幾個最不常用的關(guān)鍵字

    本篇文章是對C++中幾個最不常用的關(guān)鍵字進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C/C++實(shí)現(xiàn)動態(tài)數(shù)組的示例詳解

    C/C++實(shí)現(xiàn)動態(tài)數(shù)組的示例詳解

    動態(tài)數(shù)組相比于靜態(tài)數(shù)組具有更大的靈活性,因?yàn)槠浯笮】梢栽谶\(yùn)行時根據(jù)程序的需要動態(tài)地進(jìn)行分配和調(diào)整,本文為大家介紹了C++實(shí)現(xiàn)動態(tài)數(shù)組的方法,需要的可以參考下
    2023-08-08
  • 詳解C語言中函數(shù)宏的三種封裝方式

    詳解C語言中函數(shù)宏的三種封裝方式

    函數(shù)宏,即包含多條語句的宏定義,其通常為某一被頻繁調(diào)用的功能的語句封裝,且不想通過函數(shù)方式封裝來降低額外的彈棧壓棧開銷。本文就來聊聊函數(shù)宏的三種封裝方式吧
    2023-03-03
  • 解析C++類內(nèi)存分布

    解析C++類內(nèi)存分布

    本篇文章介紹了C++類內(nèi)存分布結(jié)構(gòu),我們來看看編譯器是怎么處理類成員內(nèi)存分布的,特別是在繼承、虛函數(shù)存在的情況下
    2021-06-06
  • C語言版醫(yī)院管理系統(tǒng)

    C語言版醫(yī)院管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言版醫(yī)院管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C++11、C++14、C++17、C++20常用新特性

    C++11、C++14、C++17、C++20常用新特性

    本文主要介紹了C++11、C++14、C++17、C++20常用新特性,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 利用Matlab編寫簡易版連連看小游戲

    利用Matlab編寫簡易版連連看小游戲

    連連看作為經(jīng)典的小游戲,一定是很多人的回憶吧。本文將用Matlab實(shí)現(xiàn)這一經(jīng)典的游戲,文中示例代碼具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評論