色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

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

什么是堆內(nèi)存?堆內(nèi)存是如何分配的?

電子工程師 ? 來源:單片機(jī)匠人 ? 作者:蔡琰老師 ? 2021-07-05 17:58 ? 次閱讀

上一篇我們分享了棧內(nèi)存的概念,現(xiàn)在我們分享下堆內(nèi)存的概念。

在一般的編譯系統(tǒng)中,堆內(nèi)存的分配方向和棧內(nèi)存是相反的。當(dāng)棧內(nèi)存從高地址向低地址增長的時候,堆內(nèi)存從低地址向高地址分配。

C語言中,堆內(nèi)存在分配和釋放的時候,是程序通過調(diào)用C語言的庫函數(shù)完成的。這和棧內(nèi)存的分配有區(qū)別,棧內(nèi)存利用的是處理器的硬件機(jī)制,而堆內(nèi)存的處理使用的是庫函數(shù)。

我們來看下堆內(nèi)存的分配情況:

在堆內(nèi)存的分配過程中,每次分配將返回一個當(dāng)前分配地址的指針。在程序中如果多次分配內(nèi)存,可以得到多個內(nèi)存指針,每個內(nèi)存指針都是本次分配內(nèi)存的地址。在釋放內(nèi)存的時候,只需要對每個指針進(jìn)行操作,那個指針?biāo)赶虻膬?nèi)存就會被釋放,而對其他的內(nèi)存區(qū)域沒有影響。

從內(nèi)存的分配和使用上,可以看出棧內(nèi)存和堆內(nèi)存的區(qū)別:棧內(nèi)存只有一個入口點,就是棧指針,棧內(nèi)存壓入和彈出的時候棧指針將發(fā)生變化,棧指針標(biāo)識當(dāng)前棧區(qū)域中已使用和未使用的界限,程序在訪問棧內(nèi)存的時候都只能通過棧指針及其偏移量;而堆內(nèi)存有多個入口點,每次分配得到的指針是訪問內(nèi)存的入口,每個分配內(nèi)存區(qū)域都可以被單獨釋放,程序?qū)Χ褍?nèi)存可以通過每次分配得到的指針訪問。

堆內(nèi)存有一個整體分配的過程,按照向上的堆內(nèi)存分配方向。隨著堆內(nèi)存使用量的增加,堆內(nèi)存將逐漸向高地址分配。這只是一個大體的增長的方面,在堆內(nèi)存中,已使用的區(qū)域和未使用的區(qū)域是交錯的,而不是像棧區(qū)域那樣有明顯的分界線。

堆內(nèi)存的釋放看下面這個圖:

看到這樣頻繁的使用區(qū)域和釋放,那么很容易看出堆內(nèi)存是不連續(xù)的,跟堆內(nèi)存的使用方式有關(guān)系,這個分配就相對自由靈活了,但是也是會在低地址向高地址發(fā)展的方向分配的。

比如上面釋放后再分配就可以是下面兩種情況:

先看再次分配1的情況:當(dāng)新分配的需求比中間(剛剛釋放)區(qū)域小,那么就會在緊接著的區(qū)域給分配。

再看再次分配2的情況:當(dāng)新分配的需求比中間(釋放的)區(qū)域大,那么只能往后尋求能給的區(qū)域。

當(dāng)頻繁的分配和釋放內(nèi)存的過程中,會很容易出現(xiàn)在兩塊已經(jīng)分配的內(nèi)存之間較小的未分配內(nèi)存區(qū)域,這些其實可以用,但是由于他們的空間比較小,不夠連續(xù)內(nèi)存的分配,所以分配的時候就很難再次使用,這些較小的內(nèi)存就是我們常說的內(nèi)存碎片。

我們再來聊一下在C程序中堆空間的使用。

在C語言中,堆內(nèi)存區(qū)域的分配和釋放是通過調(diào)用庫函數(shù)來完成的,實現(xiàn)的函數(shù)主要有四個:

void *malloc(size_t size); //分配內(nèi)存空間

void free(void *ptr); //釋放內(nèi)存空間

void *calloc(size_t nmemb,size_t size); //分配內(nèi)存空間

void *realloc(void * ptr,size_t size); //重新分配內(nèi)存空間

注意:使用上面這幾個函數(shù)需要包含標(biāo)準(zhǔn)庫文件

那么庫函數(shù)怎么使用呢,內(nèi)存分配了就要有釋放,那么常用的就是malloc()和free()兩個函數(shù)。malloc()函數(shù)的輸入是需要分配內(nèi)存的大小,輸出是分配內(nèi)存的指針。如果分配不成功,則返回NULL。

free()函數(shù)的輸入是需要釋放的指針,可以接受任何形式的指針。這個指針必須是由分配函數(shù)分配出來的。

例如:

int *pa;

pa = (int *)malloc(sizeof(int));//分配一個int大小的指針

if(NULL != pa)

{

free(pa);

}

內(nèi)存使用完成需要釋放,以便分配給其他程序使用。

calloc()也是內(nèi)存分配的,只是可以把分配好的內(nèi)存區(qū)域的初始值全部設(shè)置為0。還有這個分配內(nèi)存有兩個參數(shù),第一個是分配單元的大小,第二個是要分配的數(shù)目。

malloc(sizeof(unsigned int)*10); == calloc(sizeof(unsigned int),10)

realloc()有兩個參數(shù),一個是指向內(nèi)存的地址指針,一個是要重分配內(nèi)存的大小,返回值是指向所分配內(nèi)存的指針。

1、當(dāng)參數(shù)指針為NULL的時候,作為malloc使用,分配內(nèi)存。

2、當(dāng)重分配內(nèi)存大小為0的時候,作為free使用,釋放內(nèi)存。

3、當(dāng)指針和重分配內(nèi)存大小均不為0的時候,根據(jù)指針指向的堆內(nèi)存區(qū)域的情況和指針大小重新分配內(nèi)存。

對于realloc()作為重新分配內(nèi)存的時候,有三種可能出現(xiàn):

1、縮小內(nèi)存

2、擴(kuò)大內(nèi)存,不需要移動指針

3、擴(kuò)大內(nèi)存,需要移動指針(指定內(nèi)存區(qū)域大小不夠)

在堆內(nèi)存的管理上,主要容易出現(xiàn)以下幾個問題:

1、開辟的內(nèi)存沒有釋放,造成內(nèi)存泄漏(系統(tǒng)不會釋放任何用戶分配的內(nèi)存)

2、野指針被使用或釋放(內(nèi)存釋放后,需要將內(nèi)存指針置為NULL)

3、非法釋放指針(分配了有效內(nèi)存才存在釋放,否則是非法的)

在C語言語法的方面對棧內(nèi)存和堆內(nèi)存如何使用沒有限制。然后從使用的角度,棧內(nèi)存更適用于容量較小的單個變量(例如:C語言的基本變量類型、較小的結(jié)構(gòu)體和數(shù)組),堆內(nèi)存則適用于開辟較大塊的內(nèi)存。棧內(nèi)存由編譯器分配和釋放,堆內(nèi)存由程序員分配和釋放。

責(zé)任編輯:lq6

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

    關(guān)注

    8

    文章

    3019

    瀏覽量

    74005
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7604

    瀏覽量

    136694

原文標(biāo)題:堆內(nèi)存的那些事

文章出處:【微信號:gh_e7f294a514ca,微信公眾號:單片機(jī)匠人】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    養(yǎng)成良好的編程習(xí)慣|內(nèi)存初值不一定是0

    ;} 代碼很簡單,使用 malloc 申請一段內(nèi)存,假設(shè)內(nèi)存空間足夠大。 通過 getchar 配合 while 循環(huán),從標(biāo)準(zhǔn)輸入獲取一個字符串,直到遇到換行符結(jié)束。 最后就是把獲取的字符串輸出。 乍一看,好像程序沒什么問題。
    的頭像 發(fā)表于 12-18 09:14 ?78次閱讀

    C語言中申請的內(nèi)存能不能自動釋放

    C語言中申請的內(nèi)存能不能自動釋放?每次都要手動 free 太麻煩,也容易忘記。 學(xué)過 C++ 的同學(xué),應(yīng)該首先能想到智能指針。 但是這是C語言,沒有類和對象、構(gòu)造析構(gòu)這些技術(shù),想要自動釋放很難
    的頭像 發(fā)表于 11-27 09:33 ?108次閱讀

    Windows管理內(nèi)存的三種主要方式

    Windows操作系統(tǒng)提供了多種方式來管理內(nèi)存,以確保系統(tǒng)資源的有效利用和性能的優(yōu)化。以下是關(guān)于Windows管理內(nèi)存的三種主要方式的詳細(xì)闡述,包括內(nèi)存管理、虛擬
    的頭像 發(fā)表于 10-12 17:09 ?706次閱讀

    談JVM xmx, xms等內(nèi)存相關(guān)參數(shù)合理性設(shè)置

    的,提高內(nèi)存占用(Memory Footprint)就有可能同時優(yōu)化這兩個標(biāo)的,這篇文章就來聊聊內(nèi)存相關(guān)內(nèi)容。 內(nèi)存占用一般指應(yīng)用運行需要的所有內(nèi)存,包括
    的頭像 發(fā)表于 10-10 14:42 ?458次閱讀

    轉(zhuǎn)載 golang內(nèi)存分配

    Go 的分配采用了類似 tcmalloc 的結(jié)構(gòu).特點: 使用一小塊一小塊的連續(xù)內(nèi)存頁, 進(jìn)行分配某個范圍大小的內(nèi)存需求. 比如某個連續(xù) 8KB 專門用于
    的頭像 發(fā)表于 09-05 14:12 ?256次閱讀
    轉(zhuǎn)載 golang<b class='flag-5'>內(nèi)存</b><b class='flag-5'>分配</b>

    堆棧和內(nèi)存的基本知識

    本文主要聊聊關(guān)于堆棧的內(nèi)容。包括堆棧和內(nèi)存的基本知識。常見和堆棧相關(guān)的 bug,如棧溢出,內(nèi)存泄漏,內(nèi)存分配失敗等。后面介紹軟件中堆棧統(tǒng)計
    的頭像 發(fā)表于 08-29 14:10 ?444次閱讀
    堆棧和<b class='flag-5'>內(nèi)存</b>的基本知識

    如何使用SystemView的監(jiān)控功能

    SystemView能夠監(jiān)視應(yīng)用程序如何使用動態(tài)存儲。這意味著,如果應(yīng)用程序中使用了C或C++、自定義或RTOS提供的內(nèi)存池對象,我們可以跟蹤這些對象的使用情況。SystemView可以在一個
    的頭像 發(fā)表于 08-09 18:07 ?792次閱讀
    如何使用SystemView的<b class='flag-5'>堆</b>監(jiān)控功能

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

    、realloc、free。他們的頭文件在中,所以使用內(nèi)存管理必須包含該頭文件。二、使用方法51單片機(jī)需要使用內(nèi)存管理API必須要手動調(diào)用初始化內(nèi)存管理函數(shù):init_
    的頭像 發(fā)表于 04-26 08:10 ?1508次閱讀
    你知道嗎? 51單片機(jī)也有動態(tài)<b class='flag-5'>內(nèi)存</b><b class='flag-5'>分配</b>

    C語言內(nèi)存泄漏問題原理

    內(nèi)存泄漏問題只有在使用內(nèi)存的時候才會出現(xiàn),棧內(nèi)存不存在內(nèi)存泄漏問題,因為棧內(nèi)存會自動
    發(fā)表于 03-19 11:38 ?521次閱讀
    C語言<b class='flag-5'>內(nèi)存</b>泄漏問題原理

    Linux內(nèi)核內(nèi)存管理之內(nèi)核非連續(xù)物理內(nèi)存分配

    我們已經(jīng)知道,最好將虛擬地址映射到連續(xù)頁幀,從而更好地利用緩存并實現(xiàn)更低的平均內(nèi)存訪問時間。然而,如果對內(nèi)存區(qū)域的請求并不頻繁,那么考慮基于通過連續(xù)線性地址訪問非連續(xù)頁幀的分配方案是有意義的。該模式
    的頭像 發(fā)表于 02-23 09:44 ?947次閱讀
    Linux內(nèi)核<b class='flag-5'>內(nèi)存</b>管理之內(nèi)核非連續(xù)物理<b class='flag-5'>內(nèi)存</b><b class='flag-5'>分配</b>

    Linux內(nèi)核內(nèi)存管理之ZONE內(nèi)存分配

    內(nèi)核中使用ZONE分配器滿足內(nèi)存分配請求。該分配器必須具有足夠的空閑頁幀,以便滿足各種內(nèi)存大小請求。
    的頭像 發(fā)表于 02-21 09:29 ?890次閱讀

    拆解mmap內(nèi)存映射的本質(zhì)!

    mmap 內(nèi)存映射里所謂的內(nèi)存其實指的是虛擬內(nèi)存,在調(diào)用 mmap 進(jìn)行匿名映射的時候(比如進(jìn)行內(nèi)存
    的頭像 發(fā)表于 01-24 14:30 ?1706次閱讀
    拆解mmap<b class='flag-5'>內(nèi)存</b>映射的本質(zhì)!

    和棧的區(qū)別和使用注意事項

    和棧是在計算機(jī)科學(xué)中廣泛使用的兩種數(shù)據(jù)結(jié)構(gòu),它們具有不同的用途和特點。和棧的區(qū)別涉及到內(nèi)存分配、訪問方式、數(shù)據(jù)存儲等方面。在使用和棧時
    的頭像 發(fā)表于 01-18 17:24 ?2181次閱讀

    glibc malloc內(nèi)存分配器的實現(xiàn)原理

    內(nèi)存(Heap Memory)是一個很有意思的領(lǐng)域。你可能和我一樣,也困惑于下述問題很久了。
    的頭像 發(fā)表于 01-17 10:03 ?812次閱讀
    glibc malloc<b class='flag-5'>內(nèi)存</b><b class='flag-5'>分配</b>器的實現(xiàn)原理

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

    FreeRTOS是一種實時操作系統(tǒng),它提供了多種內(nèi)存分配方式,包括動態(tài)內(nèi)存分配和靜態(tài)內(nèi)存分配
    的頭像 發(fā)表于 12-31 16:49 ?2686次閱讀
    FreeRTOS<b class='flag-5'>內(nèi)存</b>機(jī)制詳解
    主站蜘蛛池模板: 伊人久久综合网站| 久cao在线香蕉| 午夜影视不用充钱的免费| 二级特黄绝大片免费视频大片| 秋霞电影网午夜鲁丝片无码| bl(高h)文| 青柠高清在线观看完整版| 把手戳进美女尿口里动态图| 日韩美一区二区| 国产AV视频二区在线观看| 我和黑帮老大第365天第2季在线| 国产精品久久久久久熟妇吹潮软件 | 综合久久久久久久综合网| 久久受www免费人成_看片中文| 正能量不良WWW免费窗口| 美国z0069| www.伊人网| 手机在线观看mv网址| 国产人妻麻豆蜜桃色69| 亚洲欧美综合中文字幕| 久久无码AV亚洲精品色午夜麻豆 | vidosgratis tv少女| 日本午夜精品一区二区三区电影 | 千禧金瓶梅 快播| 国产91专区| 亚洲精品成人在线| 久久精品嫩草影院免费看| 91久久精一区二区三区大全| 欧美一区二区在线观看| 国产高清国内精品福利色噜噜| 亚洲大码熟女在线| 久久久免费观成人影院| 99热在线观看| 玩弄人妻少妇500系列网址| 极品美女久久久久久久久久久| 中文字幕一区中文亚洲| 欧美一区二区在线观看| 国产一卡在线观看完整版| 再插深点嗯好大好爽| 欧美乱码伦视频免费66网| 国产精品久久久久久52AVAV |