0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

動(dòng)態(tài)內(nèi)存分配的注意事項(xiàng)及本質(zhì)是什么

C語(yǔ)言編程學(xué)習(xí)基地 ? 來(lái)源:華為云社區(qū) ? 作者:G-washington ? 2021-10-13 15:37 ? 次閱讀

C語(yǔ)言中比較重要的就是指針,它可以用來(lái)鏈表操作,談到鏈表,很多時(shí)候?yàn)榇朔峙鋬?nèi)存采用動(dòng)態(tài)分配而不是靜態(tài)分配。

本文分享自華為云社區(qū)《 【云駐共創(chuàng)】C語(yǔ)言中動(dòng)態(tài)內(nèi)存分配的本質(zhì) 》,作者:G-washington

C語(yǔ)言是一門(mén)面向過(guò)程的、抽象化的通用程序設(shè)計(jì)語(yǔ)言,廣泛應(yīng)用于底層開(kāi)發(fā)。盡管C語(yǔ)言提供了許多低級(jí)處理的功能,但仍然保持著跨平臺(tái)的特性,因?yàn)镃語(yǔ)言具有可移植性,可拓展性,可重用性等特性,促使C語(yǔ)言仍然在編程語(yǔ)言排行榜上占據(jù)一定有利地位。而C語(yǔ)言中比較重要的就是指針,它可以用來(lái)鏈表操作,談到鏈表,很多時(shí)候?yàn)榇朔峙鋬?nèi)存采用動(dòng)態(tài)分配而不是靜態(tài)分配。

內(nèi)存分配的概念

通常定義變量(或?qū)ο螅?,編譯器在編譯時(shí)都可以根據(jù)該變量(或?qū)ο螅┑念愋椭浪鑳?nèi)存空間的大小,從而系統(tǒng)在適當(dāng)?shù)臅r(shí)候?yàn)樗麄兎峙浯_定的存儲(chǔ)空間。這種內(nèi)存分配稱為靜態(tài)存儲(chǔ)分配;

有些操作對(duì)象只在程序運(yùn)行時(shí)才能確定,這樣編譯時(shí)就無(wú)法為他們預(yù)定存儲(chǔ)空間,只能在程序運(yùn)行時(shí),系統(tǒng)根據(jù)運(yùn)行時(shí)的要求進(jìn)行內(nèi)存分配,這種方法稱為動(dòng)態(tài)存儲(chǔ)分配。所有動(dòng)態(tài)存儲(chǔ)分配都在堆區(qū)中進(jìn)行。

內(nèi)存不是取之不盡用之不竭,4g、8g、16g是常見(jiàn)的電腦內(nèi)存大小,打開(kāi)任務(wù)管理器,能看到不同的應(yīng)用占據(jù)的內(nèi)存情況。如果一個(gè)應(yīng)用程序占了大部分內(nèi)存,估計(jì)別的應(yīng)用就資源緊張了,那這個(gè)應(yīng)用可能會(huì)被卸載,找個(gè)節(jié)省內(nèi)存的。

內(nèi)存管理是計(jì)算機(jī)接近物理本質(zhì)的操作,那些程序語(yǔ)言之下的動(dòng)作,最終都要調(diào)動(dòng)內(nèi)存來(lái)實(shí)現(xiàn)。系統(tǒng)的資源不是無(wú)限的,系統(tǒng)上運(yùn)行的程序也不是只有這一個(gè),忽略內(nèi)存,就會(huì)設(shè)計(jì)出危險(xiǎn)的、冗余的代碼產(chǎn)品,或者沒(méi)法更好的交互。

動(dòng)態(tài)內(nèi)存分配的特點(diǎn)

動(dòng)態(tài)內(nèi)存是相對(duì)靜態(tài)內(nèi)存而言的。所謂動(dòng)態(tài)和靜態(tài)就是指內(nèi)存的分配方式。動(dòng)態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存。動(dòng)態(tài)內(nèi)存分配的本質(zhì)就是,什么時(shí)候需要一塊內(nèi)存的時(shí)候,再分配這塊內(nèi)存;當(dāng)不再需要某一塊內(nèi)存的時(shí)候,就可以把這塊內(nèi)存釋放掉。這種靈活的內(nèi)存分配方式,正好適合鏈表這種數(shù)據(jù)結(jié)構(gòu)。

傳統(tǒng)數(shù)組的缺點(diǎn)

數(shù)組與動(dòng)態(tài)內(nèi)存分配相比有以下缺點(diǎn):

數(shù)組的長(zhǎng)度必須事先指定,而且只能是常量,不能是變量。

因?yàn)閿?shù)組長(zhǎng)度只能是常量,所以它的長(zhǎng)度不能在函數(shù)運(yùn)行的過(guò)程當(dāng)中動(dòng)態(tài)地?cái)U(kuò)充和縮小。

對(duì)于數(shù)組所占內(nèi)存空間程序員無(wú)法手動(dòng)編程釋放,只能在函數(shù)運(yùn)行結(jié)束后由系統(tǒng)自動(dòng)釋放,所以在一個(gè)函數(shù)中定義的數(shù)組只能在該函數(shù)運(yùn)行期間被其他函數(shù)使用。

而“傳統(tǒng)數(shù)組”的問(wèn)題,實(shí)際上就是靜態(tài)內(nèi)存的問(wèn)題。但是動(dòng)態(tài)內(nèi)存就不存在這個(gè)問(wèn)題,因?yàn)閯?dòng)態(tài)內(nèi)存是由程序員手動(dòng)編程釋的,所以想什么時(shí)候釋放就什么時(shí)候釋放。只要程序員不手動(dòng)編程釋放,就算函數(shù)運(yùn)行結(jié)束,動(dòng)態(tài)分配的內(nèi)存空間也不會(huì)被釋放,其他函數(shù)仍可繼續(xù)使用它。除非是整個(gè)程序運(yùn)行結(jié)束,這時(shí)系統(tǒng)為該程序分配的所有內(nèi)存空間都會(huì)被釋放。

動(dòng)態(tài)內(nèi)存的申請(qǐng)與釋放

動(dòng)態(tài)內(nèi)存的申請(qǐng)與釋放主要依靠?jī)蓚€(gè)函數(shù)malloc和free。malloc 是一個(gè)系統(tǒng)函數(shù),它是 memory allocate 的縮寫(xiě)。其中memory是“內(nèi)存”的意思,allocate是“分配”的意思。顧名思義 malloc 函數(shù)的功能就是“分配內(nèi)存”,要調(diào)用它必須要包含頭文件《stdlib.h》。

malloc()函數(shù)會(huì)向堆中申請(qǐng)一片連續(xù)的可用內(nèi)存空間;若申請(qǐng)成功 ,,返回指向這片內(nèi)存空間的指針 ,若失敗 ,則會(huì)返回NULL, 所以我們?cè)谟胢alloc()函數(shù)開(kāi)辟動(dòng)態(tài)內(nèi)存之后, 一定要判斷函數(shù)返回值是否為NULL;返回值的類型為void*型, malloc()函數(shù)并不知道連續(xù)開(kāi)辟的size個(gè)字節(jié)是存儲(chǔ)什么類型數(shù)據(jù)的 ,所以需要我們自行決定 ,方法是在malloc()前加強(qiáng)制轉(zhuǎn) ,轉(zhuǎn)化成我們所需類型 ,如: (int*)malloc(sizeof(int)*n)。

下面使用 malloc 函數(shù)寫(xiě)一個(gè)程序,程序的功能是:調(diào)用被調(diào)函數(shù),將主調(diào)函數(shù)中動(dòng)態(tài)分配的內(nèi)存中的數(shù)據(jù)放大 10 倍。

249605c0-2bf7-11ec-82a8-dac502259ad0.png

輸出結(jié)果是:*p = 100

free是釋放函數(shù),在堆中申請(qǐng)的內(nèi)存空間不會(huì)像在棧中存儲(chǔ)的局部變量一樣 ,函數(shù)調(diào)用完會(huì)自動(dòng)釋放內(nèi)存 , 如果我們不手動(dòng)釋放, 直到程序運(yùn)行結(jié)束才會(huì)釋放, 這樣就可能會(huì)造成內(nèi)存泄漏, 即堆中這片內(nèi)存中的數(shù)據(jù)已經(jīng)不再使用, 但它一直占著這片空間, 所以當(dāng)我們申請(qǐng)的動(dòng)態(tài)內(nèi)存不再使用時(shí) ,一定要及時(shí)釋放 。不過(guò)需要注意的是,釋放并不是指清空內(nèi)存空間,而是指將該內(nèi)存空間標(biāo)記為“可用”狀態(tài),使操作系統(tǒng)在分配內(nèi)存時(shí)可以將它重新分配給其他變量使用。

那么,當(dāng)指針變量被釋放后,它所指向的內(nèi)存空間中的數(shù)據(jù)會(huì)怎樣呢?free 的標(biāo)準(zhǔn)行為只是表示這塊內(nèi)存可以被再分配,至于它里面的數(shù)據(jù)是否被清空并沒(méi)有強(qiáng)制要求。不同的編譯器處理的方式可能不一樣。我們就看一下 VC++6.0 這個(gè)編譯器是怎么處理的:

252281da-2bf7-11ec-82a8-dac502259ad0.png

可見(jiàn)在 VC++6.0 中,當(dāng)指針變量被釋放后,雖然它仍然是指向那個(gè)內(nèi)存空間的,但那個(gè)內(nèi)存空間中的值將會(huì)被重新置一個(gè)非常小的負(fù)數(shù)。動(dòng)態(tài)創(chuàng)建的內(nèi)存如果不用了必須要釋放。注意,一個(gè)動(dòng)態(tài)內(nèi)存只能釋放一次。如果釋放多次程序就會(huì)崩潰,因?yàn)橐呀?jīng)釋放了,不能再釋放第二次。

綜上所述,malloc 和 free 一定要成對(duì)存在,一一對(duì)應(yīng)。有 malloc 就一定要有 free,有幾個(gè) malloc 就要有幾個(gè) free,與此同時(shí),每釋放一個(gè)指向動(dòng)態(tài)內(nèi)存的指針變量后要立刻把它指向 NULL。

注意事項(xiàng)

1)釋放一塊內(nèi)存的一部分是不允許的。動(dòng)態(tài)分配的內(nèi)存必須整塊一起釋放。但是,realloc函數(shù)可以縮小一塊動(dòng)態(tài)分配的內(nèi)存,有效地釋放它尾部的部分內(nèi)存。

2)不要訪問(wèn)已經(jīng)被free函數(shù)釋放了的內(nèi)存。假定對(duì)一個(gè)指向動(dòng)態(tài)分配的內(nèi)存的指針進(jìn)行了復(fù)制,而且這個(gè)指針的幾份拷貝分散于程序各處。你無(wú)法保證當(dāng)你使用其中一個(gè)指針時(shí)它所指向的內(nèi)存是不是已被另一個(gè)指針釋放。還要確保程序中所有使用這塊內(nèi)存的地方在這塊內(nèi)存釋放之前停止對(duì)它的使用。

3)當(dāng)動(dòng)態(tài)分配的內(nèi)存不再需要使用時(shí),應(yīng)該被釋放,這樣可以被重新分配使用。分配內(nèi)存但在使用完畢后不釋放將引起內(nèi)存泄漏(memory leak)。

今天的分享就到這里了,大家要好好學(xué)C++喲~

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7581

    瀏覽量

    135605
  • 程序
    +關(guān)注

    關(guān)注

    115

    文章

    3749

    瀏覽量

    80672
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4262

    瀏覽量

    62237
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4697

    瀏覽量

    68099
  • 動(dòng)態(tài)內(nèi)存

    關(guān)注

    1

    文章

    24

    瀏覽量

    7957

原文標(biāo)題:C語(yǔ)言核心基礎(chǔ)知識(shí):動(dòng)態(tài)內(nèi)存分配的本質(zhì)是什么?

文章出處:【微信號(hào):cyuyanxuexi,微信公眾號(hào):C語(yǔ)言編程學(xué)習(xí)基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    繞線電感定制的注意事項(xiàng)

    電子發(fā)燒友網(wǎng)站提供《繞線電感定制的注意事項(xiàng).docx》資料免費(fèi)下載
    發(fā)表于 09-20 11:24 ?0次下載

    內(nèi)幕揭秘:電流檢測(cè)放大器的滿量程和動(dòng)態(tài)范圍注意事項(xiàng)

    電子發(fā)燒友網(wǎng)站提供《內(nèi)幕揭秘:電流檢測(cè)放大器的滿量程和動(dòng)態(tài)范圍注意事項(xiàng).pdf》資料免費(fèi)下載
    發(fā)表于 09-12 09:11 ?0次下載
    內(nèi)幕揭秘:電流檢測(cè)放大器的滿量程和<b class='flag-5'>動(dòng)態(tài)</b>范圍<b class='flag-5'>注意事項(xiàng)</b>

    共模電感定制的注意事項(xiàng)

    電子發(fā)燒友網(wǎng)站提供《共模電感定制的注意事項(xiàng).docx》資料免費(fèi)下載
    發(fā)表于 09-04 11:47 ?0次下載

    LiFePO4設(shè)計(jì)注意事項(xiàng)

    電子發(fā)燒友網(wǎng)站提供《LiFePO4設(shè)計(jì)注意事項(xiàng).pdf》資料免費(fèi)下載
    發(fā)表于 09-03 09:24 ?0次下載
    LiFePO4設(shè)計(jì)<b class='flag-5'>注意事項(xiàng)</b>

    FMD LINK 使用注意事項(xiàng)

    電子發(fā)燒友網(wǎng)站提供《FMD LINK 使用注意事項(xiàng).pdf》資料免費(fèi)下載
    發(fā)表于 05-06 10:11 ?0次下載

    你知道嗎? 51單片機(jī)也有動(dòng)態(tài)內(nèi)存分配

    一、簡(jiǎn)述其實(shí)在51單片機(jī)中也可以使用動(dòng)態(tài)內(nèi)存,動(dòng)態(tài)內(nèi)存其實(shí)就是劃出一塊內(nèi)存區(qū)域,將這塊內(nèi)存進(jìn)行管理,稱為內(nèi)存管理。51單片機(jī)可以使用c語(yǔ)言自
    的頭像 發(fā)表于 04-26 08:10 ?1228次閱讀
    你知道嗎? 51單片機(jī)也有<b class='flag-5'>動(dòng)態(tài)內(nèi)存</b><b class='flag-5'>分配</b>

    C語(yǔ)言中的動(dòng)態(tài)內(nèi)存管理講解

    本章將講解 C 中的動(dòng)態(tài)內(nèi)存管理。C 語(yǔ)言為內(nèi)存分配和管理提供了幾個(gè)函數(shù)。這些函數(shù)可以在 頭文件中找到。
    的頭像 發(fā)表于 02-23 14:03 ?348次閱讀
    C語(yǔ)言中的<b class='flag-5'>動(dòng)態(tài)內(nèi)存</b>管理講解

    浪涌抑制器的應(yīng)用及注意事項(xiàng)?

    浪涌抑制器的應(yīng)用及注意事項(xiàng)?|深圳比創(chuàng)達(dá)電子
    的頭像 發(fā)表于 01-19 09:55 ?629次閱讀
    浪涌抑制器的應(yīng)用及<b class='flag-5'>注意事項(xiàng)</b>?

    堆和棧的區(qū)別和使用注意事項(xiàng)

    介紹堆和棧的區(qū)別和使用注意事項(xiàng),包括內(nèi)存分配、數(shù)據(jù)存儲(chǔ)、訪問(wèn)速度、生命周期等方面,幫助讀者更好地理解和應(yīng)用堆和棧。 一、堆和棧的區(qū)別 內(nèi)存分配
    的頭像 發(fā)表于 01-18 17:24 ?1899次閱讀

    測(cè)速電機(jī): 常見(jiàn)6大注意事項(xiàng)

    測(cè)速電機(jī): 常見(jiàn)6大注意事項(xiàng)!測(cè)速電機(jī)是一種用于測(cè)量物體運(yùn)動(dòng)速度的設(shè)備,廣泛應(yīng)用于工業(yè)生產(chǎn)和科學(xué)研究中。測(cè)速電機(jī)常見(jiàn)的6大注意事項(xiàng)以確保安全和準(zhǔn)確性。
    的頭像 發(fā)表于 01-11 10:53 ?383次閱讀
    測(cè)速電機(jī): 常見(jiàn)6大<b class='flag-5'>注意事項(xiàng)</b>

    FreeRTOS內(nèi)存機(jī)制詳解

    FreeRTOS是一種實(shí)時(shí)操作系統(tǒng),它提供了多種內(nèi)存分配方式,包括動(dòng)態(tài)內(nèi)存分配和靜態(tài)內(nèi)存分配。
    的頭像 發(fā)表于 12-31 16:49 ?2343次閱讀
    FreeRTOS<b class='flag-5'>內(nèi)存</b>機(jī)制詳解

    霍爾元件使用的注意事項(xiàng)

    霍爾元件使用的注意事項(xiàng)? 霍爾元件是一種常見(jiàn)的電子元件,主要用于測(cè)量和檢測(cè)磁場(chǎng)的變化。它具有靈敏度高、響應(yīng)速度快、耐磁場(chǎng)干擾等優(yōu)點(diǎn),在各種應(yīng)用中得到廣泛使用。然而,為了確?;魻栐恼9ぷ骱脱娱L(zhǎng)其
    的頭像 發(fā)表于 12-18 14:56 ?1128次閱讀

    電流互感器的使用注意事項(xiàng)

    當(dāng)談到電流互感器的使用時(shí),有一些重要的注意事項(xiàng)需要我們牢記。在本文中,我們將探討這些注意事項(xiàng),為您提供詳細(xì)和全面的信息。
    的頭像 發(fā)表于 12-15 10:34 ?1221次閱讀
    電流互感器的使用<b class='flag-5'>注意事項(xiàng)</b>

    VGA OUT 的PCB設(shè)計(jì)注意事項(xiàng)

    VGA OUT 的PCB設(shè)計(jì)注意事項(xiàng)
    的頭像 發(fā)表于 11-23 09:04 ?735次閱讀

    動(dòng)態(tài)補(bǔ)償裝置的元件構(gòu)成與注意事項(xiàng)有哪些?

    動(dòng)態(tài)補(bǔ)償裝置的元件構(gòu)成與注意事項(xiàng)有哪些? 動(dòng)態(tài)補(bǔ)償裝置是一種用于對(duì)電力系統(tǒng)中的無(wú)功功率進(jìn)行補(bǔ)償?shù)难b置,它通過(guò)引入無(wú)功功率,來(lái)提高電力系統(tǒng)的功率因素,降低無(wú)功電流,改善線路的負(fù)載情況,從而提高電網(wǎng)運(yùn)行
    的頭像 發(fā)表于 11-06 11:27 ?518次閱讀