freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

第十章目標(biāo)程序運行時的組織-資料下載頁

2025-08-01 13:35本頁面
  

【正文】 ray ( int sz) { size= sz。 // allocate an integer array of size // and set ia to point to it ia= new int [size]。 // initialize array for (int i=0。isz。++i) ia[i]=0。 } C++語言中 new操作符施加在一個類型標(biāo)識符上 ( 包括類名 ) Pascal語言中 , 標(biāo)準(zhǔn)過程 new能夠動態(tài)建立存儲空間并相應(yīng)地置上指針 。 標(biāo)準(zhǔn)過程dispose是釋放空間 . new與 dispose不斷改變著堆存儲器的使用情況 。 C語言中有這些操作的若干個版本 , 但最基本的是 malloc 和 free , 它 們 都 是 標(biāo) 準(zhǔn) 庫( ) 的一部分 堆式動態(tài)存儲分配 需求: 一個程序語言允許用戶自由地申請數(shù)據(jù)空間和退還數(shù)據(jù)空間 , 或者不僅有過程而且有進(jìn)程 ( process)的程序結(jié)構(gòu) , 操作: 堆提供兩個操作 , 分配操作和釋放操作 情況 : 經(jīng)一段運行時間之后,這個大空間就必定被分劃成許多塊塊,有些占用,有些無用(空閑) 碎片問題 堆式動態(tài)儲分配 當(dāng)運行程序要求一塊體積為 N的空間時,我們應(yīng)該分配哪一塊給它呢? 運行程序要求一塊體積為 N的空間,但發(fā)現(xiàn)沒有比 N大的空閑塊了,然而所有空閑塊的總和卻要比 N大得多 如果運行程序要求一塊積為 N的空間,但所有空閑塊的總和也不夠 N,那又應(yīng)怎么辦呢?有的管理系統(tǒng)采用一種叫做垃圾回收的辦法來對付這種局面。即尋找那些運行程序業(yè)己無用但尚未釋放的占用塊 堆管理 堆空間的管理策略 減少碎片的技術(shù) 空間的釋放 堆空間的管理策略 1 定長塊管理 2 變長塊管理 堆式動態(tài)儲分配的實現(xiàn) 1 定長塊管理 堆式動態(tài)儲分配最簡單的實現(xiàn)是按定長塊進(jìn)行 。初始化時 , 將堆存儲空間分成長度相等的若干塊 , 每塊中指定一個鏈域 , 按照鄰塊的順序把所有塊鏈成一個鏈表 , 用指針 available指向鏈表中的第一塊 。 分配時每次都分配指針 available所指的塊 , 然后available指向相鄰的下一塊 。 歸還時 , 把所歸還的塊插入鏈表 。 考慮插入方便 , 可以把所歸還的塊插在 available 所指的塊之前 , 然后available指向新歸還的塊 。 2 變長塊管理 除了按定長塊進(jìn)行分配之外,還可以根據(jù)需要分配長度不同的存儲塊,可以隨要求而變。按這種方法,初始化時存儲空間是一個整塊。按照用戶的需要,分配時先是從一個整塊里分割出滿足需要的一小塊,以后,歸還時,如果新歸還的塊和現(xiàn)有的空間能合并,則合并成一塊;如果不能和任何空閑塊合并,則可以把空閑塊鏈成一個鏈表。再進(jìn)行分配時,從空閑塊鏈表中找出滿足需要的一塊,或者整塊分配出去,或者從該塊上分割一小塊分配出去。若空閑塊表中有若干個滿足需要的空閑塊時,該分配哪一塊呢?通常有三種不同的分配策略 不同的情況應(yīng)采用不同的方法。通常在選擇時需考慮下列因素:用戶的要求;請求分配量的大小分布;分配和釋放的頻率以及效率對系統(tǒng)的重要等等。 ( 1) 首次滿足法:只要在空閑塊鏈表中找到滿足需要的一塊 ,就進(jìn)行分配 。 ( 2) 最優(yōu)滿足法:將空閑塊鏈表中一個不小于申請塊且最接近于申請塊的空閑塊分配給用戶 , 則系統(tǒng)在分配前首先要對空閑塊鏈表從頭至尾描一遍 , 然后從中找出一塊 , 為避免每次分配都要掃描整個鏈表 , 通常將空閑塊鏈表空間的大小從小到大排序 。 ( 3) 最差滿足法:將空閑塊表中不小于申請塊且是最大的空閑的一部全分配給用戶 。 此時的空閑塊鏈表按空閑的塊的大小從大到小排序 。 只需從鏈表中刪除第一個結(jié)點 , 并將其中一部分分配給用戶 , 而其它部分作為一個新的結(jié)點插入到空閑塊表的適當(dāng)置上去 。 減少碎片的技術(shù) 1分配時,找最小的足夠大的塊 需保持空閑塊的大小排序 2 釋放時,合并任何相鄰的塊 搜索全部空閑塊表,或其它算法 3 將堆變量緊縮在一起 空間的釋放 1顯式釋放 2隱式(自動)釋放 顯式釋放 程序設(shè)計語言提供機(jī)制 如: pascal 的 dispose C 的 free 程序員必須編寫分配和釋放存儲的明確的調(diào)用 注意的問題 1 堆變量是不可訪問的(垃圾) 2 懸掛(不安全)指針 堆式分配和釋放的 C語言描述 define NULL 0 define MEMSIZE 8096 /* change for different sizes */ typedef fdouble Align。 typedef union header {struct {union header *next。 unsigned usedsize。 unsigned freesize。 }s。 Align a。 }Header。//數(shù)據(jù)類型 Header保存每個存儲塊的簿記信息 static Header mem [MEMSIZE]。 static Header *memptr= NULL。 void *malloc (unsigned nbytes) {Header *p, *newp。 unsigned nunits。 nunits= (nbytes+sizeof (Header)1/ sizeof (Header)+1。 if (memptr == NULL) {memptrs. next = memptr = mem。 memptrs. usedsize = 1。 memptrs. freesize = MEMSIZE1。 } for (p=memptr。 (ps. next!= memptr) amp。amp。(ps. freesize nunits)。 p=ps. next)。 if (ps. freesize nunits) return NULL。 /* no block big enough */ newp = p+ps. usedsize。 newps. usedsize= nunits。 newps. freesize = ps. freesizenunits。 newp = ps. next。 ps. freesize=0。 ps. next= newp。 memptr=newp。 return (void *)(newp+1)。 } void free (void *ap) {Header * bp, *p, *prev。 bp= (Header *) ap –1。 for (prev= memptr, p=memptrs. next。 (p!=bp) amp。amp。(p!= memptr)。 prev=p, p=ps. next)。 if (p!=bp) return。 /* corrupted list, do nothing */ prevs. freesize += ps. usedsize + ps. freesize。 prevs. next = ps. next。 memptr = prev。 } 堆的自動管理 隱式存儲回收 在一種需要完全動態(tài)的運行時環(huán)境的語言( OO語言 , 函數(shù)式語言 Lisp,ML)中 , 堆也必須類似地自動管理 。 自動存儲器管理涉及到了前面分配的但不再使用的存儲器的回收 , 可能是在它被分配的很久以后 ,而沒有明確的對 free的調(diào)用 。 這個過程稱作垃圾回收 ( grabage collection) 。 垃圾回收 垃圾回收程序 尋找可被引用的所有存儲器并釋所有未引用的存儲器。 在存儲塊不再引用時,無論是直接還是通過指針間接的引用,識別這些存儲塊是一項比維護(hù)堆存儲 的列表復(fù)雜得多的任務(wù)。 方法 對 malloc的調(diào)用失敗,激活垃圾回收程序 垃圾回收算法 mark and sweep 隱式存儲回收 —mark and sweep算法 隱式存儲回收要求用戶程序和支持運行的回收子程序并行工作,因為回收程序需要知道分配給用戶程序的存儲塊何時不再使用。為了實現(xiàn)并行工作,在存儲塊中要設(shè)置回收子程序訪問的信息。 存儲塊格式: 塊長度 訪問計數(shù)標(biāo)記 指針 用戶使用空間 回收過程 分為兩個階段 。 ( 1) 第一個階段為標(biāo)記階段 , 對已分配的塊跟蹤程序中各指針的訪問路徑 。 如果某個塊被訪問過 , 就給這個塊加一個標(biāo)記 。 ( 2) 第二個階段為回收階段 , 所有未加標(biāo)記的存儲塊回收到一起 , 并插入空閑塊鏈表中 , 然后消除在存儲塊中所加的全部標(biāo)記 。 面向?qū)ο蟮恼Z言中的動態(tài)存儲器 面向?qū)ο蟮恼Z言在運行時環(huán)境中要求特殊的機(jī)制以完成其增添的特性:對象 、 方法 、繼承以及動態(tài)聯(lián)編 。 面向?qū)ο笳Z言在對運行時方面的要求差異很大 。 Smalltalk要求與 LISP相似的完全動態(tài)環(huán)境 C++則保持 C的基于棧的環(huán)境 實現(xiàn)對象 實現(xiàn)對象的一個簡單機(jī)制是,初始化代碼將所有當(dāng)前的繼承特征(和方法)直接地復(fù)制到記錄結(jié)構(gòu)中(將方法當(dāng)作代碼指針)。但這樣做極浪費空間。 另外一種方法是在執(zhí)行時將類結(jié)構(gòu)的一個完整的描述保存在每個點的存儲器中,并由超類指針維護(hù)繼承性(有時這也稱作繼承圖( inheritance graph))。接著同用于它的實例變量的域一起,每個對象保持一個指向其定義類的指針,通過這個類就可找到所有(局部和繼承的)的方法。此時,只記錄一次方法指針(在類結(jié)構(gòu)中),而且對于每個對象并不將其復(fù)制到存儲器中。由于是通過類繼承的搜索來找到這個機(jī)制的,所以該機(jī)制還實現(xiàn)繼承性與動態(tài)聯(lián)編。其缺 在于:雖然實例變量具有可預(yù)測的偏移量(正如在標(biāo)準(zhǔn)環(huán)境中的局部變量一樣),方法卻沒有,而且它們必須由帶有查詢功能的符號表結(jié)構(gòu)中的名字維護(hù)。這是對于諸如 Smalltalk的高度動態(tài)語言的合理的結(jié)構(gòu),因為類結(jié)構(gòu)可以在執(zhí)行中改變。 C++中選擇的方法 將整個類結(jié)構(gòu)保存在環(huán)境中 , 計算出每個類的可用方法的代碼指針列表 , 并將其作為一個虛擬函數(shù)表 ( virtual function table) 而存放在( 靜態(tài) ) 存儲器 。 它的優(yōu)點在于:可做出安排以使每個方法都有一個可預(yù)測的偏移量 ,而且也不再需要用一系列表查詢遍歷類的層次結(jié)構(gòu) 。 現(xiàn)在每個對象都包括了一個指向相應(yīng)的虛擬函數(shù)表而不是類結(jié)構(gòu)的指針 ( 當(dāng)然 ,這個指針的位置必須也有可預(yù)測的偏移量 ) 。 例 C++類聲明: class A {public: double x,y。 void f()。 virtual void g()。 }。 class B:public A {public: double z。 void f()。 virtual void h()。 }。 類 A的一個對象應(yīng)出現(xiàn)在存儲器中 ( 帶有它的虛擬函數(shù)表 ) 而類 B的一個對象則應(yīng)如下所示: x y vtp A::g B::h A::g X Y vtp z
點擊復(fù)制文檔內(nèi)容
環(huán)評公示相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1