日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

最近花了點時間讀了《深入理解C指針》這本書,讀完這本書后,對于之前嵌入式C語言開發中很多一知半解的地方豁然開朗。對于之前學習以及工作中,很多沒有注意的問題,也有了更加深刻的理解和認識。今天就花點時間整理下這段時間讀完這本書后的所學所得,也方便后續查看。

我們在開發C語言程序的時候,程序需要在編譯器中編譯后,才能在對應產品中運行。在程序運行的過程中,內存的分配一般分為以下幾個部分:

  • 堆(heap)
  • 棧(stack)
  • BSS區
  • 數據區
  • 代碼區

對于我們平時開發的C程序,加載到處理器的內存中運行,呈現出來的結構就大概分為以上五個區域。為了更好地理解,我們可以根據下面這張圖去理解。

對于內存結構的簡單理解

 

下面我們簡單地對上述幾個區域做一下介紹。首先從代碼區開始。


代碼區

我們需要了解的是,我們在使用C語言開發產品程序代碼的時候,最終的開發好的程序是并不能直接在產品的處理器中直接運行的。而是需要經過編譯器的編譯,最終將我們的代碼轉換成CPU處理器所能夠理解的機器指令,才能在CPU中正常運行。而代碼區,我們可以簡單地理解為我們編寫好的程序(已經轉換為機器指令的程序代碼)存放的地方。CPU處理器會從這個地方取出機器指令去完成對應的操作,最終實現我們想讓CPU所實現的功能(簡單的算術運算,或者對應的硬件操作等)。

棧區

棧區,這個區域不需要我們去維護管理,在程序運行的過程中,會自動的分配和釋放。可能有些人不太能理解這個區域是做什么用的,這里我們簡單地做一下介紹。

我們在開發嵌入式C程序代碼的過程中,經常會在定義一些函數,去完成特定的功能(例如:定義一個addfunc函數用于實現兩個數的加法運算,或者說更加復雜的,定義一個函數來對一個鏈表進行查詢操作),在這些函數中,我們不可避免地,會去定義一些局部變量(局部變量的概念就不在這里做介紹了,不理解的建議去過一遍譚浩強的C語言程序開發)。在程序運行的過程中,我們需要一個地方去存儲我們定義的這些局部變量,調用函數時的參數值,返回值等,而這個地方就是棧。

棧區是處于不斷變化的狀態中,舉個例子,當前,程序運行在main函數中,此時棧中存儲的則是main函數中我們定義的一些局部變量。這個時候,假如我們在main函數中去調用其他函數,那么,棧中會自動進行出棧操作,然后再進行入棧操作,將我們調用的那個函數的相關的局部變量,函數參數,返回值等都壓入到棧中。如下圖所示:

對于內存結構的簡單理解

 

最先開始,程序從main函數開始運行,在調用addfunc函數之前,棧中的存儲內容可能是這樣的。

對于內存結構的簡單理解

 


對于內存結構的簡單理解

 

而在調用了addfunc函數后,棧區的內容就會被自動地替換為addfunc函數中的局部變量等內容。在返回main函數后,又會自動進行出棧入棧操作。

對于內存結構的簡單理解

 

我們在不斷地調用函數的同時,也自動不斷地進行入棧以及出棧的操作,也就是說,我們定義的局部變量,實際上是在內存上不是一直會存在的,可能會在某一次的入棧及出棧操作中被覆蓋掉。舉個例子,我們可以試著編譯運行下面這段代碼。

對于內存結構的簡單理解

 

這里我們在main函數中定義了一個局部變量a和b,以及一個res變量。接著我們調用addfunc函數,先將a和b變量的值進行相加,然后存儲到res變量中。最后輸出結果。看到這里,如果對C語言有點基礎的朋友,就知道這種做法是得不到我們想要的預期結果的。而這就是因為我們程序在運行過程中,棧區不斷進行入棧出棧導致的。我們在main函數中定義了a,b和res后,調用addfunc函數,此時棧區會進行出棧以及入棧操作,在addfunc函數中,做完加法運算后,res變量的值存儲在棧中某個地址中,但是在addfunc函數返回后,會被下一次出棧入棧操作給覆蓋掉。因此我們得不到我們想要的結果。

堆區

上面介紹完棧區后,我們這里再簡單說下堆區。其實堆區和棧區,指向的是同一片內存區域。不同的是,這兩個區域在這一塊內存區域的兩頭,隨著程序的運行,根據需要,一個不斷向下增長,一個不斷向上增長。(如下圖)這也是我們經常喜歡說“堆棧“,而不是將這兩個地方單獨說”棧區“或”堆區“的原因。

對于內存結構的簡單理解

 

堆區不同于棧區的另一個地方,就是我們程序想要在堆上開辟內存使用,方法不同于棧。在C程序中,我們定義了一個局部變量并賦值,這個過程可以理解為我們在棧上開辟了一個空間來使用,而且我們不需要去理會這個空間后續的回收問題。但是在堆上開辟空間的方法則不同。我們可以調用malloc函數在堆上開辟我們所需要使用的內存空間。在最后這段空間使用完畢后,則需要我們再調用free函數來釋放掉我們申請的這段空間。否則就會發生內存泄露問題。當內存泄露的次數多了,則可能出現堆棧溢出。簡單的說,就是我們一直向系統索要內存空間來使用,卻忘記了“歸還“,系統內存空間是有限的,當系統內存空間不夠程序運行使用時,則會導致堆棧溢出,程序再也無法正常運行。

BSS區

這個區域存放的是未初始化的全局變量和靜態變量。

數據區

這個區域存放的是已初始化的全局變量和靜態變量,以及常量等。如下圖:

對于內存結構的簡單理解

 

我們在main函數中,定義了a,b,c三個變量,a和b變量均保存去數據區中,而c是一個指針,是局部變量,存放的是“hello world”字符串的地址,而這個字符串則存在于數據區。如下圖

對于內存結構的簡單理解

 

分享到:
標簽:內存 結構
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定