【緩衝區溢出】堆溢出原理

 

一、操作系統中堆和棧的區別

 

堆內存申請,釋放,操作,特點:
1. 堆內存申請環境:堆內存需要程序員在程序中申請 ,動態分配,申請的大小有程序決定。
2. 堆內存申請方法:C語言中的malloc() 函數 , c++ 中的new()函數。堆內存進行申請時候可能會申請失敗,申請成功與失敗與計算機性能,當前運行環境等有關。    
3. 堆內存釋放:申請過後的堆內存不能由系統自動進行釋放,C語言中採用 free() 函數,c++中採用 delete() 函數進行釋放內存。
4. 堆內存操作:申請過後的內存,會返回指向堆內存的指針,後續對於內存的讀寫等操作需要通過此指針進行。
5. 堆內存特點:地址由低向高生長。  堆內存非線性,呈現無序狀態。因此用到了鏈表。

棧內存的申請,釋放,操作,特點:
1. 棧內存的申請是在程序中定義好的,比如數組,包括棧的大小,包含的變量(存儲局部變量,數組,棧幀,函數返回地址等)  
2. 棧內存的釋放是有程序自身決定的不用掉用函數,當程序退出時,棧內存會自動銷燬,維持棧平衡,否則就會發生內存訪問錯誤。
3. 棧內存的操作 push pop 只有這兩種操作。  
4. 棧內存的特點:由高地址向低地址生長,呈現線性規劃。參考OD中棧緩衝區向上增長,即向低地址增長。

 

二、堆-heap

1、動態內存分配的方法

動態內存分配(Dynamic memory allocation)又稱爲堆內存分配,是指計算機程序在運行期中分配使用內存。它可以當成是一種分配有限內存資源所有權的方法。 動態分配的內存在被程序員明確釋放或被垃圾回收之前一直有效。與靜態內存分配的區別在於沒有一個固定的生存期。這樣被分配的對象稱之爲有一個“動態生存期”。

2、堆內存中數據結構——堆塊、堆表

① 堆塊
出於對性能的考慮,堆區的內存按照不同大小的內存塊被組織起來,以字節爲單位。
堆塊的結構:堆塊分爲塊首塊身
塊首的結構:塊首包含當前堆塊的主要信息例如:堆塊的大小,空閒態還是佔用態等狀態表信息。
對塊首的識別:當連續進行內存申請時,如果返回的指針地址是有差距的,兩個連續的指針之間的差距就是第二個塊身的塊首。
塊身的結構:塊身就是本堆塊存放數據的位置,即最終分配給用戶的數據區。
塊身位置:塊身位於塊首的後面緊挨着。
對塊身的操作: 申請堆區成功後返回的指針直接指向的塊身的首地址,對塊身的操作也就是對堆區的操作

② 堆表

堆表的意義:堆表用來索引堆塊。堆表中包含所有堆塊的大小,位置,狀態等信息。堆表的數據結構決定了堆區的組織方式,是快速檢索空閒塊,保證堆分配效率的關鍵。堆表進行設計的時候會考慮二叉樹平衡策略,快速查找策略等。現代的操作系統中堆表的數據結構還不止一種。像一個字典一樣用來查找堆塊,並且在 windows 中索引的是所有空閒態的堆塊。

這裏需要嚴格區分一點:佔用態的堆塊使用自己的程序索引,堆表只索引所有空閒態的堆塊。重要的堆表包含兩類:空閒雙向鏈表(簡稱空表),快速單向鏈表(塊表)。下面逐一對其要點進行分析。

空表(空閒雙向鏈表)

1. 堆區空閒堆塊的塊首都包含一對指針,這對指針用於將空閒的堆塊組織成雙向鏈表,按照大小的不同,總共分爲128條。
2. 堆區一開始的堆表區中,有一個128項的指針數組,叫空表數組索引,該數組的每一項都包含兩個指針,用來標示一條空表。
3. 空表的結構如下:

 

 

塊表(快速單向鏈表)

 

 

 

 

參考:

https://www.jianshu.com/p/c082b014fdf9

https://www.jianshu.com/p/59cc7c8a44d3

https://www.kanxue.com/chm.htm?id=10532&pid=node1000986

 

 

 

 

發佈了66 篇原創文章 · 獲贊 30 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章