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

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

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

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

嵌入式C語言之堆和棧介紹

冬至子 ? 來源:南山府嵌入式 ? 作者:編外人員 ? 2023-05-20 15:04 ? 次閱讀

前言

嵌入式C語言中,堆和棧都是用來存儲變量的內(nèi)存區(qū)域,但它們在存儲和使用變量方面有很大的區(qū)別。

堆和棧的主要區(qū)別在于它們的分配和釋放方式。棧是由編譯器自動分配和釋放的,存儲在棧中的變量的生命周期與函數(shù)調(diào)用的生命周期相同。每次函數(shù)調(diào)用時,棧會自動分配一些內(nèi)存用于存儲函數(shù)的參數(shù)、局部變量和返回地址等信息,當函數(shù)返回時,棧中的這些變量和信息會自動被釋放。

需要注意的是,堆和棧的大小都是有限制的。棧的大小通常受限于系統(tǒng)的硬件資源和操作系統(tǒng)的限制,而堆的大小通常受限于操作系統(tǒng)的內(nèi)存管理策略和硬件資源。如果在程序中使用了過多的堆或棧內(nèi)存,可能會導(dǎo)致棧溢出或堆溢出等內(nèi)存錯誤,從而導(dǎo)致程序崩潰或行為不可預(yù)測。因此,在編寫嵌入式C程序時,應(yīng)該合理地使用堆和棧內(nèi)存,避免出現(xiàn)內(nèi)存錯誤。

一、堆和棧的概念

區(qū)別:

堆和棧都是內(nèi)存中的一段連續(xù)區(qū)域,用于存儲數(shù)據(jù)。它們之間的區(qū)別在于:

棧是由編譯器自動管理的,其內(nèi)存分配和釋放都由編譯器負責(zé),開發(fā)者無法直接控制。而堆是由開發(fā)者手動管理的,需要通過調(diào)用相關(guān)的函數(shù)來申請和釋放內(nèi)存空間。

  • 棧是一種先進后出(LIFO)的數(shù)據(jù)結(jié)構(gòu),通常位于內(nèi)存的高地址區(qū)域。棧的特點是具有自動分配和釋放內(nèi)存的能力,每次函數(shù)調(diào)用時,程序會自動為該函數(shù)分配一個棧幀,并在函數(shù)返回時自動釋放棧幀。由于棧的內(nèi)存分配和釋放由編譯器自動完成,因此程序員無需手動管理棧內(nèi)存。棧內(nèi)存主要用于存儲局部變量、函數(shù)參數(shù)和返回值等數(shù)據(jù)。
  • 堆是一種動態(tài)數(shù)據(jù)結(jié)構(gòu),通常位于內(nèi)存的低地址區(qū)域。堆的特點是可以在運行時動態(tài)分配和釋放內(nèi)存,程序員可以通過malloc、calloc等函數(shù)手動申請一塊指定大小的內(nèi)存空間,并在使用完畢后手動釋放該內(nèi)存空間。堆內(nèi)存主要用于存儲動態(tài)分配的數(shù)據(jù),如數(shù)組、結(jié)構(gòu)體和對象等。

堆的定義:

堆是指存放在內(nèi)存中的一塊動態(tài)分配的區(qū)域,它的大小是不固定的,可以在程序運行時動態(tài)地分配和釋放。堆的分配和釋放由程序員來控制,程序員需要手動地分配堆的內(nèi)存空間,并在不需要時釋放它。堆是一種動態(tài)分配的內(nèi)存區(qū)域,通常用于存儲一些比較大的數(shù)據(jù)結(jié)構(gòu),例如數(shù)組和結(jié)構(gòu)體等。

棧的定義

棧是指存放在內(nèi)存中的一塊靜態(tài)分配的區(qū)域,它的大小是固定的,不能在程序運行時動態(tài)地分配和釋放。棧的分配和釋放由系統(tǒng)自動控制,系統(tǒng)會自動地為每個線程分配一塊??臻g。棧是一種后進先出(Last In First Out,LIFO)的數(shù)據(jù)結(jié)構(gòu),通常用于存儲一些較小的數(shù)據(jù),例如基本數(shù)據(jù)類型和函數(shù)的參數(shù)等。

堆的實現(xiàn)方式及存放數(shù)據(jù)類型

堆是動態(tài)內(nèi)存分配中的一種方式,其內(nèi)存空間是在程序運行期間從系統(tǒng)中申請的,因此能夠更加靈活地利用內(nèi)存空間。堆的實現(xiàn)方式一般是通過malloc、calloc、realloc等函數(shù)來實現(xiàn)。這些函數(shù)會在系統(tǒng)的堆空間中申請一塊指定大小的內(nèi)存空間,并返回一個指向該內(nèi)存空間的指針。

堆可以存放各種類型的數(shù)據(jù),包括基本數(shù)據(jù)類型、數(shù)組、結(jié)構(gòu)體、指針等等。下面以數(shù)組和結(jié)構(gòu)體為例,分別演示在堆中動態(tài)分配內(nèi)存空間的方法。

棧和堆的異同點

內(nèi)存分配和釋放方式不同

棧內(nèi)存是由編譯器自動分配和釋放的,它的生命周期與函數(shù)的生命周期相同。每當函數(shù)被調(diào)用時,編譯器將自動為該函數(shù)分配一塊內(nèi)存,用于存儲該函數(shù)的局部變量、參數(shù)、返回值以及函數(shù)的返回地址等信息。當函數(shù)執(zhí)行完畢后,編譯器將自動釋放該函數(shù)的內(nèi)存空間。

堆內(nèi)存是由程序員動態(tài)分配和釋放的。程序員可以根據(jù)需要動態(tài)地分配內(nèi)存空間,同時在不再需要該內(nèi)存空間時手動釋放它。堆內(nèi)存的生命周期由程序員決定,因此程序員必須確保及時釋放堆內(nèi)存,以避免內(nèi)存泄漏。

舉例:

1#include 
 2#include 
 3
 4void foo(int n) {
 5    int x = n * n;
 6    printf("x = %d\\n", x);
 7}
 8
 9int main() {
10    int a = 10;
11    foo(a);
12
13    int* p = (int*)malloc(sizeof(int));
14    *p = 20;
15    printf("*p = %d\\n", *p);
16    free(p);
17
18    return 0;
19}

在上面的示例中,變量a是一個整型變量,它被存儲在棧上。函數(shù)foo也被存儲在棧上,它的參數(shù)n和局部變量x也被存儲在棧上。變量p是一個指向整型變量的指針,它被存儲在棧上,但它指向的內(nèi)存空間是在堆上動態(tài)分配的。在代碼的結(jié)尾,使用free函數(shù)手動釋放了p指向的堆內(nèi)存。

訪問速度不同

棧的內(nèi)存訪問速度比堆快,因為棧內(nèi)存是連續(xù)的,可以直接通過指針訪問,而堆內(nèi)存是非連續(xù)的,需要通過指針間接訪問。

內(nèi)存大小不同

棧的內(nèi)存大小通常受到系統(tǒng)的限制,可以通過調(diào)整系統(tǒng)棧大小來改變棧的容量。而堆的內(nèi)存大小通常受到系統(tǒng)內(nèi)存的限制,可以通過調(diào)用malloc、calloc等函數(shù)來動態(tài)分配內(nèi)存空間。

數(shù)據(jù)存儲方式

棧中存儲的數(shù)據(jù)通常是局部變量、參數(shù)、返回地址等信息。由于棧的特殊結(jié)構(gòu),棧中的數(shù)據(jù)存儲方式是先進后出,即后進先出。

堆中存儲的數(shù)據(jù)通常是程序員動態(tài)分配的內(nèi)存,例如動態(tài)數(shù)組、鏈表等。由于堆的靈活性,堆中的數(shù)據(jù)存儲方式并不固定。

兩者存放的數(shù)據(jù)

棧中存放的數(shù)據(jù)

嵌入式系統(tǒng)中,C語言棧是用于存儲局部變量、函數(shù)參數(shù)和返回地址等信息的一段連續(xù)的內(nèi)存空間。通常情況下,??臻g是在程序運行時動態(tài)分配的,大小由編譯器決定。主要是如下幾類:

  • 函數(shù)的參數(shù):在函數(shù)調(diào)用時,參數(shù)會被壓入棧中,以供函數(shù)使用。
  • 函數(shù)的局部變量:函數(shù)內(nèi)部定義的局部變量會被存儲在棧中,函數(shù)執(zhí)行完畢后,這些變量會被銷毀。
  • 函數(shù)調(diào)用的返回地址:在函數(shù)調(diào)用時,程序需要記錄下一個返回地址,以便函數(shù)執(zhí)行完畢后返回到正確的位置,這個返回地址也被存儲在棧中。
  • 函數(shù)執(zhí)行過程中的臨時變量:函數(shù)執(zhí)行過程中可能需要使用一些臨時變量,這些變量也會被存儲在棧中。

在嵌入式C語言中,堆是一個動態(tài)分配內(nèi)存的區(qū)域,它通常用于存放一些較大的數(shù)據(jù)結(jié)構(gòu)、動態(tài)分配的對象和需要在函數(shù)調(diào)用之間傳遞的數(shù)據(jù)。與棧不同,堆中的數(shù)據(jù)不會隨著函數(shù)的調(diào)用而自動釋放,需要程序員手動管理。

  1. 動態(tài)分配的對象:在運行時動態(tài)分配的對象,如結(jié)構(gòu)體、數(shù)組、字符串等。
  2. 大型數(shù)據(jù)結(jié)構(gòu):堆可以存儲較大的數(shù)據(jù)結(jié)構(gòu),如圖像、音頻、視頻等。
  3. 全局變量:在程序運行期間需要一直存在的全局變量可以存儲在堆中。

需要在函數(shù)調(diào)用之間傳遞的數(shù)據(jù):有些數(shù)據(jù)需要在函數(shù)調(diào)用之間傳遞,但是它們的大小超出了棧的容量限制,這些數(shù)據(jù)可以存儲在堆中。

如何避免溢出?

在嵌入式系統(tǒng)中,棧的大小是有限的,因此在編寫嵌入式C代碼時需要格外注意棧的使用。如果??臻g不夠,可能會導(dǎo)致棧溢出,這會破壞程序的正常執(zhí)行,甚至導(dǎo)致系統(tǒng)崩潰。

  1. 合理設(shè)置棧的大?。涸诰帉懘a時需要預(yù)估每個函數(shù)所需要的??臻g,并合理設(shè)置棧的大小,以確保棧空間不會被耗盡。
  2. 減少遞歸調(diào)用:遞歸調(diào)用可能導(dǎo)致??臻g的大量消耗,因此應(yīng)該盡量避免在嵌入式系統(tǒng)中使用遞歸調(diào)用。
  3. 使用靜態(tài)變量或全局變量:在需要保存狀態(tài)的情況下,可以考慮使用靜態(tài)變量或全局變量來代替局部變量,這樣可以避免在棧中分配過多的空間。
  4. 使用堆內(nèi)存:對于較大的數(shù)據(jù)結(jié)構(gòu)或需要動態(tài)分配內(nèi)存的情況,可以考慮使用堆內(nèi)存,這樣可以避免??臻g的浪費和棧溢出的風(fēng)險。

  1. 避免過度分配內(nèi)存:在使用堆內(nèi)存時,應(yīng)該盡量避免過度分配內(nèi)存。如果程序需要的內(nèi)存大小能夠預(yù)估,可以提前分配足夠的內(nèi)存,避免動態(tài)分配過多的內(nèi)存。
  2. 及時釋放內(nèi)存:在程序不再使用某個內(nèi)存塊時,應(yīng)該及時釋放它,避免內(nèi)存泄漏的問題。同時,在釋放內(nèi)存時,也應(yīng)該確保不會釋放已經(jīng)被釋放的內(nèi)存塊,避免重復(fù)釋放的問題。
  3. 避免內(nèi)存碎片:在頻繁地分配和釋放小塊內(nèi)存時,容易導(dǎo)致內(nèi)存碎片的產(chǎn)生。為了避免內(nèi)存碎片,可以使用內(nèi)存池等技術(shù)優(yōu)化內(nèi)存管理。
  4. 確保線程安全:在多線程環(huán)境下使用堆內(nèi)存時,需要確保線程安全,避免出現(xiàn)競爭條件和死鎖的問題。
  5. 避免堆溢出:堆溢出是指堆中的內(nèi)存使用超出了堆的容量限制,導(dǎo)致程序崩潰或出現(xiàn)不可預(yù)期的行為。為了避免堆溢出,需要合理設(shè)置堆的大小,并進行嚴格的內(nèi)存管理。
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 嵌入式系統(tǒng)
    +關(guān)注

    關(guān)注

    41

    文章

    3593

    瀏覽量

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

    關(guān)注

    180

    文章

    7604

    瀏覽量

    136841
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1634

    瀏覽量

    49133
  • LIFO
    +關(guān)注

    關(guān)注

    0

    文章

    3

    瀏覽量

    12139
收藏 人收藏

    評論

    相關(guān)推薦

    嵌入式C語言之變量與常量簡析

      如何學(xué)習(xí)編程c++語言?粵嵌來講解嵌入式C語言在各種項目中要用到的知識點,尤其是嵌入式
    發(fā)表于 12-15 06:27

    嵌入式SQL語句與主語言之間的通信

    嵌入式SQL嵌入式SQL語句與主語言之間的通信為了區(qū)分SQL語句與主語言語句,所有SQL語句必須加前綴EXEC SQL 主語言
    發(fā)表于 12-22 07:44

    硬件層面的基本介紹

    !基本介紹嵌入式和單片機開發(fā)領(lǐng)域中,是非常重要的基礎(chǔ)知識,但對于許多開發(fā)者來說,
    發(fā)表于 03-01 07:40

    嵌入式C語言進階之道

    C 語言的書有一大,嵌入 C 語言的書也不少,但都不過是簡單
    發(fā)表于 04-19 10:15

    嵌入式c語言編程(由淺入深)

    本內(nèi)容詳細介紹嵌入式c語言編程的各項知識,包括嵌入式c語言
    發(fā)表于 11-02 14:37 ?0次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>c</b><b class='flag-5'>語言</b>編程(由淺入深)

    嵌入式C編程

    嵌入式C編程,非常有用的資料,介紹嵌入式C語言編程
    發(fā)表于 12-29 17:29 ?0次下載

    嵌入式C_C++語言精華

    介紹了在嵌入式開發(fā)的過程中,c語言C++語言的施用技巧。
    發(fā)表于 03-17 09:54 ?2次下載

    嵌入式C的主要特點以及嵌入式C與標準C異同沖區(qū)重用

    嵌入式C發(fā)展迅速, 而且成為最受歡迎的語言之一, 主要因為它具有強大的功能。用嵌入式C加上一些匯編語言
    發(fā)表于 05-29 14:24 ?3776次閱讀

    C語言內(nèi)存的筆記資料說明

    本文檔的主要內(nèi)容詳細介紹的是C語言內(nèi)存的筆記資料說明說明了C
    發(fā)表于 02-14 08:00 ?3次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>內(nèi)存<b class='flag-5'>堆</b>與<b class='flag-5'>棧</b>的筆記資料說明

    嵌入式外中斷c語言代碼

    嵌入式外中斷c語言代碼(arm嵌入式開發(fā)實例)-嵌入式外中斷c
    發(fā)表于 07-30 11:29 ?4次下載
    <b class='flag-5'>嵌入式</b>外中斷<b class='flag-5'>c</b><b class='flag-5'>語言</b>代碼

    嵌入式C語言-文件操用

    嵌入式C語言-文件操用(嵌入式開發(fā)需要什么證書)-嵌入式C
    發(fā)表于 07-30 11:56 ?15次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>C</b><b class='flag-5'>語言</b>-文件操用

    淺談嵌入式 MCU 軟件開發(fā)之應(yīng)用工程的

    堆棧的定義和作用2. 嵌入式 C 語言應(yīng)用工程的大小確定3. 嵌入式 C
    發(fā)表于 10-28 20:21 ?2次下載
    淺談<b class='flag-5'>嵌入式</b> MCU 軟件開發(fā)之應(yīng)用工程的<b class='flag-5'>堆</b>與<b class='flag-5'>棧</b>

    C語言嵌入式培訓(xùn) 嵌入式C語言程序設(shè)計基礎(chǔ)

      學(xué)習(xí)嵌入式的基礎(chǔ)語言C語言,因此先掌握C語言對于后續(xù)
    發(fā)表于 11-03 21:06 ?32次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>嵌入式</b>培訓(xùn)  <b class='flag-5'>嵌入式</b><b class='flag-5'>C</b><b class='flag-5'>語言</b>程序設(shè)計基礎(chǔ)

    嵌入式C語言的區(qū)別

    嵌入式C語言中,都是用來存儲變量的內(nèi)存區(qū)域,但它們在存儲和使用變量方面有很大的區(qū)別。
    的頭像 發(fā)表于 04-14 11:45 ?1414次閱讀

    嵌入式C語言的結(jié)構(gòu)特點

    嵌入式開發(fā)中既有底層硬件的開發(fā)又涉及上層應(yīng)用的開發(fā),即涉及系統(tǒng)的硬件和軟件,C語言既具有匯編語言操作底層的優(yōu)勢,又具有高級語言功能性強的特點
    的頭像 發(fā)表于 11-24 16:16 ?693次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>C</b><b class='flag-5'>語言</b>的結(jié)構(gòu)特點
    主站蜘蛛池模板: avtt国产| 日操夜操天天操| 久久99精品久久久久久秒播 | 亚洲成a人片8888kkkk| 优优优色| 黄色一级片网址| 欧美黄色影院| 黄视频免费观看| 美女视频很黄很a免费国产| 天天操夜夜操狠狠操| 欧美操穴视频| 午色| 国产单男| 国产精品久久久亚洲第一牛牛| 4438x成人全国最大| 天天做夜夜做久久做狠狠| 成人在线一区二区三区| 最新丁香六月| 欧美xxxx色视频在线观看免费| 亚洲久久草| 91视频www| 特级黄毛片| 一级免费视频| 狠狠操狠狠插| 一级黄免费| 国产拍拍| 不卡午夜| 天堂电影在线观看免费入口| 国产精品9999久久久久仙踪林 | 噜噜嘿| 欧美簧片| 伊人精品在线观看| 国产三级日产三级日本三级| 高黄网站| 四虎永久免费在线观看| 在线观看色视频网站| 老湿影院免费体验区| 日本三级成人午夜视频网| 天天摸日日碰天天看免费| 亚洲一区二区影视| 人人爱爱|