chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

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

3天內不再提示

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

電子工程師 ? 來源:單片機匠人 ? 作者:蔡琰老師 ? 2021-07-05 17:58 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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()也是內存分配的,只是可以把分配好的內存區(qū)域的初始值全部設置為0。還有這個分配內存有兩個參數,第一個是分配單元的大小,第二個是要分配的數目。

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

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

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

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

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

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

1、縮小內存

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

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

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

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

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

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

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

責任編輯:lq6

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

    關注

    9

    文章

    3231

    瀏覽量

    76501
  • C語言
    +關注

    關注

    183

    文章

    7646

    瀏覽量

    146120

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

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

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    LuatOS的內存分配機制

    不同 LuatOS 硬件平臺在內存布局上存在差異,Lua 運行內存、系統內存與 PSRAM 擴展內存分配方式各有區(qū)別。部分型號將系統與腳本
    的頭像 發(fā)表于 04-16 12:37 ?90次閱讀
    LuatOS的<b class='flag-5'>內存</b><b class='flag-5'>分配</b>機制

    DDR5內存斷崖式下跌或引發(fā)踩踏式拋貨?

    內存
    芯廣場
    發(fā)布于 :2026年03月30日 15:35:23

    MangoTree Halo Ultra「全新PXI」,標配自動糾錯內存#

    內存
    芒果樹數字
    發(fā)布于 :2026年03月06日 15:59:34

    curl中的TFTP實現:整數下溢導致內存越界讀取漏洞

    可能已經超過了已分配的緩沖區(qū)大小。緊接著的第12行 sendto 調用就可能發(fā)送超出緩沖區(qū)邊界的數據。 1 2 3 4 5 6 7 8 9 10 影響 此漏洞的潛在影響是信息泄露,即可能將內存中的內容
    發(fā)表于 02-19 13:55

    keil中c語言的動態(tài)分配內存

    于處理器的指令集中,效率很高,但是分配內存容量有限。另外,當函數運行結束時,棧區(qū)的空間會被自動釋放。 (3)內存映射段。該部分內存主要用于文件映射、動態(tài)庫以及匿名映射。 (4)
    發(fā)表于 01-21 06:04

    【「Linux 設備驅動開發(fā)(第 2 版)」閱讀體驗】+讀深入理解Linux內核內存分配

    每個內存地址是虛擬的,不是直接指向RAM中的任何地址。當用戶訪問內存中的存儲單元時,都會進行地址轉換以匹配相應的物理內存。書籍的第10章討論了五個主題,對Linux內核內存
    發(fā)表于 01-16 20:05

    嵌入式系統中,動態(tài)分配內存可能發(fā)生的問題是什么?

    盡管不像非嵌入式計算機那么常見,嵌入式系統還是有從(heap)中動態(tài)分配內存的過程的。 那么嵌入式系統中,動態(tài)分配內存可能發(fā)生的問題是什
    發(fā)表于 12-22 09:42

    三種類型內存的使用

    給上級調用函數。通常被稱為“”。 靜態(tài)存儲:在程序的整個生命周期內有效。在進程啟動時分配,全局變量都存儲在這里。 如果想通過一個函數“返回”內存,不必通過調用 malloc,可以直接將一個指向
    發(fā)表于 12-12 06:43

    使用Keil MicroLIB時自動設置大小

    項目的過程中,市場遇到各種各樣問題,棧穿透到里面,或者不夠大,相當煩人! 有時候就在想,何不讓全局變量以外的所有RAM給堆棧共用? 因為從低到高分配,而棧從高到低
    發(fā)表于 12-09 07:04

    和棧的區(qū)別

    一個由C/C 編譯的程序占用的內存分為以下幾個部分: 棧區(qū)(stack):由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于數據結構中的棧。 區(qū)(heap):一般由
    的頭像 發(fā)表于 11-27 18:13 ?1224次閱讀

    如何在應用程序調試期間分析棧和使用情況

    隨著 AMD Vitis 統一軟件平臺 2021.2 的發(fā)布,Vitis 引入了一個 Tcl 腳本,用于在應用程序運行的特定時間點協助查找棧和內存使用情況。該腳本已延續(xù)到后續(xù)的 Vitis 版本
    的頭像 發(fā)表于 10-24 16:54 ?1037次閱讀
    如何在應用程序調試期間分析棧和<b class='flag-5'>堆</b>使用情況

    WebGL/Canvas 內存泄露分析

    的 JavaScript 對象未釋放要復雜得多。一個現代 WebGL/Canvas 應用的內存版圖實際上跨越了三個截然不同但又相互關聯的內存區(qū)域: 圖 V8 引擎管理的 JavaScript (JS Heap
    的頭像 發(fā)表于 10-21 11:40 ?532次閱讀
    WebGL/Canvas <b class='flag-5'>內存</b>泄露分析

    stm32cubeIDE使用malloc失敗是什么原因?

    我在stm32cubeIDE環(huán)境下,已經分配了足夠的棧與空間,但是我在的使用malloc分配內存時,一直分配不成功,這是什么原因?
    發(fā)表于 06-09 07:24

    stm32cubeIDE使用malloc失敗是什么原因?

    我在stm32cubeIDE環(huán)境下,已經分配了足夠的棧與空間,但是我在的使用malloc分配內存時,一直分配不成功,這是什么原因?
    發(fā)表于 06-04 07:18