在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

什么是堆內存?堆內存是如何分配的?

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

上一篇我們分享了棧內存的概念,現在我們分享下堆內存的概念。

在一般的編譯系統中,堆內存的分配方向和棧內存是相反的。當棧內存從高地址向低地址增長的時候,堆內存從低地址向高地址分配。

C語言中,堆內存在分配和釋放的時候,是程序通過調用C語言的庫函數完成的。這和棧內存的分配有區別,棧內存利用的是處理器的硬件機制,而堆內存的處理使用的是庫函數。

我們來看下堆內存的分配情況:

在堆內存的分配過程中,每次分配將返回一個當前分配地址的指針。在程序中如果多次分配內存,可以得到多個內存指針,每個內存指針都是本次分配內存的地址。在釋放內存的時候,只需要對每個指針進行操作,那個指針所指向的內存就會被釋放,而對其他的內存區域沒有影響。

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

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

堆內存的釋放看下面這個圖:

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

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

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

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

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

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

在C語言中,堆內存區域的分配和釋放是通過調用庫函數來完成的,實現的函數主要有四個:

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

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

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

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

注意:使用上面這幾個函數需要包含標準庫文件

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

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

例如:

int *pa;

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

if(NULL != pa)

{

free(pa);

}

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

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

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

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

1、當參數指針為NULL的時候,作為malloc使用,分配內存。

2、當重分配內存大小為0的時候,作為free使用,釋放內存。

3、當指針和重分配內存大小均不為0的時候,根據指針指向的堆內存區域的情況和指針大小重新分配內存。

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

1、縮小內存

2、擴大內存,不需要移動指針

3、擴大內存,需要移動指針(指定內存區域大小不夠)

在堆內存的管理上,主要容易出現以下幾個問題:

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

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

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

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

責任編輯:lq6

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 內存
    +關注

    關注

    8

    文章

    3115

    瀏覽量

    75065
  • C語言
    +關注

    關注

    180

    文章

    7630

    瀏覽量

    140740

原文標題:堆內存的那些事

文章出處:【微信號:gh_e7f294a514ca,微信公眾號:單片機匠人】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    如何使用LAX_CODEGEN啟用動態內存分配

    我目前正在探索NXP_MBDToolbox_LAX。lax_codegen 生成的代碼基于靜態分配。我想管理大型向量,如何使用 LAX_CODEGEN 啟用動態內存分配
    發表于 04-10 08:09

    :整流電路的“中流砥柱”

    大家好!今天我們來聊一聊電子電路中一個非常重要的元器件——橋。無論是家用電器、工業設備,還是通信設備,橋都扮演著不可或缺的角色。它雖然看起來不起眼,但卻是整流電路的“中流砥柱”。那么,橋到底是
    的頭像 發表于 04-01 17:07 ?687次閱讀

    golang內存分配

    作者:錢文 Go 的分配采用了類似 tcmalloc 的結構.特點: 使用一小塊一小塊的連續內存頁, 進行分配某個范圍大小的內存需求. 比如某個連續 8KB 專門用于
    的頭像 發表于 03-31 15:00 ?156次閱讀
    golang<b class='flag-5'>內存</b><b class='flag-5'>分配</b>

    養成良好的編程習慣|內存初值不一定是0

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

    C語言中申請的內存能不能自動釋放

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

    Windows管理內存的三種主要方式

    Windows操作系統提供了多種方式來管理內存,以確保系統資源的有效利用和性能的優化。以下是關于Windows管理內存的三種主要方式的詳細闡述,包括內存管理、虛擬
    的頭像 發表于 10-12 17:09 ?2263次閱讀

    談JVM xmx, xms等內存相關參數合理性設置

    的,提高內存占用(Memory Footprint)就有可能同時優化這兩個標的,這篇文章就來聊聊內存相關內容。 內存占用一般指應用運行需要的所有內存,包括
    的頭像 發表于 10-10 14:42 ?1234次閱讀

    轉載 golang內存分配

    Go 的分配采用了類似 tcmalloc 的結構.特點: 使用一小塊一小塊的連續內存頁, 進行分配某個范圍大小的內存需求. 比如某個連續 8KB 專門用于
    的頭像 發表于 09-05 14:12 ?458次閱讀
    轉載 golang<b class='flag-5'>內存</b><b class='flag-5'>分配</b>

    內存管理的硬件結構

    常見的內存分配函數有malloc,mmap等,但大家有沒有想過,這些函數在內核中是怎么實現的?換句話說,Linux內核的內存管理是怎么實現的?
    的頭像 發表于 09-04 14:28 ?605次閱讀
    <b class='flag-5'>內存</b>管理的硬件結構

    如何自定義內存控制器的設置

    在FreeRTOS中自定義內存控制器的設置,主要涉及到內存分配策略的選擇和配置。FreeRTOS提供了多種內存分配策略,如heap_1、he
    的頭像 發表于 09-02 14:28 ?871次閱讀

    堆棧和內存的基本知識

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

    如何使用SystemView的監控功能

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

    NONOS 1.5.3/1.5.4 SSL內存泄漏的原因?

    我已經通過隨附的代碼驗證了當發生 SSL 握手錯誤時,會生成內存泄漏 此外,espconn_reconnect_callback不稱為信令ESPCONN_HANDSHAKE - TCP SSL 握手
    發表于 07-18 07:24

    (RTOS_SDK)mbedtls_ssl_write內存不足怎么解決?

    內存不足時,該函數mbedtls_ssl_write永遠卡住,大約3-4kb的。ssl_write將永遠阻塞,直到您重置設備,它僅在內存
    發表于 07-17 07:57

    單相整流橋怎么測量好壞

    單相整流橋是一種常見的電子元件,主要用于將交流電轉換為直流電。在測量單相整流橋的好壞時,需要掌握一定的方法和技巧。 一、單相整流橋的基本概念 1.1 單相整流橋的定義 單相整流
    的頭像 發表于 07-16 09:22 ?2093次閱讀
    主站蜘蛛池模板: 啪啪网免费 | 被公侵犯肉体中文字幕一区二区 | 又黄又涩的视频 | 91寡妇天天综合久久影院 | 性瘾高h姚蕊全文免费阅读 性做久久久久 | 丁香五香天堂网 | 亚洲综合资源 | 永久看日本大片免费 | 最近高清在线国语 | 亚洲四虎| 精品新一区二区三区四区 | 亚洲精品成人久久久影院 | 欧美一级视频免费看 | 爱爱免费网站 | 天天夜天天干 | 国产精品不卡片视频免费观看 | 手机国产看片 | 视频在线观看一区二区 | 在线视频网址免费播放 | 久久婷婷人人澡人人爱91 | 亚洲成人毛片 | 国产大片黄在线观看 | 特黄特色| 天天躁夜夜躁狠狠躁躁88 | 狠狠色丁香六月色 | 国产精品毛片天天看片 | 亚洲精品中文字幕乱码三区一二 | 樱桃磁力bt天堂 | 色多多免费观看在线 | 五月天色网址 | 六月色 | 国产精品理论 | 被公侵犯肉体中文字幕一区二区 | 天天操天天操天天操天天操 | 天堂在线中文无弹窗全文阅读 | 久碰香蕉精品视频在线观看 | 操人网站| 速度与激情在线 | 久久精品在 | 曰本女人色黄网站 | 七月婷婷在线视频综合 |