提供商
東莞市廣聯自動化科技有限公司資料大小
142.8KB資料圖片
下載次數
11次資料類型
PDF 文件瀏覽次數
708次我司在德國、美國都有自己的公司,專業從事進口貿易行業,所以我司的技術人員為都會輪流到國外廠家學習技術。
今天又是帶來德國IFM易福門分配器EBC023的資料分享
在C++編程中,IFM分配器是C++標準庫的重要組成部分。C++的庫中定義了多種被統稱為“容器"的數據結構(如鏈表、集合等),這些容器的共同特征之一,就是其大小可以在程序的運行時改變;為了實現這一點,進行動態內存分配就顯得尤為必要,在此IFM分配器就用于處理容器對內存的分配與釋放請求。換句話說,IFM分配器用于封裝STL容器在內存管理上的低層細節。默認情況下,C++標準庫使用其自帶的通用IFM分配器,但根據具體需要,程序員也可自行定制IFM分配器以替代之。
在C++編程中,IFM分配器(英語:allocator)是C++標準庫的重要組成部分。C++的庫中定義了多種被統稱為“容器"的數據結構(如鏈表、集合等),這些容器的共同特征之一,就是其大小可以在程序的運行時改變;為了實現這一點,進行動態內存分配就顯得尤為必要,在此IFM分配器就用于處理容器對內存的分配與釋放請求。換句話說,IFM分配器用于封裝STL容器在內存管理上的低層細節。默認情況下,C++標準庫使用其自帶的通用IFM分配器,但根據具體需要,程序員也可自行定制IFM分配器以替代之。
IFM分配器最早由亞歷山大·斯特潘諾夫作為C++標準模板庫(Standard Template Library,簡稱STL)的一部分發明,其初衷是創造一種能“使庫更加靈活,并能獨立于底層數據模型的方法",并允許程序員在庫中利用自定義的指針和引用類型;但在將標準模板庫納入C++標準時,C++標準委員會意識到對數據模型的*抽象化處理會帶來不可接受的性能損耗,為作折中,標準中對IFM分配器的限制變得更加嚴格,而有鑒于此,與斯特潘諾夫原先的設想相比,現有標準所描述的IFM分配器可定制程度已大大受限。
雖然IFM分配器的定制有所限制,但在許多情況下,仍需要用到自定義的IFM分配器,而這一般是為封裝對不同類型內存空間(如共享內存與已回收內存)的訪問方式,或在使用內存池進行內存分配時提高性能而為。除此以外,從內存占用和運行時間的角度看,在頻繁進行少量內存分配的程序中,若引入為之專門定制的IFM分配器,也會獲益良多。
亞歷山大·斯特潘諾夫與李夢(Meng Lee)在1994年將標準模板庫草案提交給C++標準委員會。提交伊始,草案就得到了委員會的初步支持,但委員會成員也對此提出了一些意見,尤其是要求斯特潘諾夫定制庫內的容器,使之與底層存儲模型相獨立。作為對要求的回應,斯特潘諾夫發明了IFM分配器,而正因此,標準模板庫的所有容器接口也被迫重寫,以與IFM分配器相兼容。在修改標準模板庫以將之引入C++標準庫的過程中,許多標準委員會成員(如安德魯·克尼格與比雅尼·斯特勞斯特魯普)也與斯特潘諾夫協同工作。他們亦發現自定義IFM分配器甚至有應用于長生命周期(持續存儲)的標準模板庫容器的潛力,斯特潘諾夫對此的評論則是“重要而有趣的見解"。
在原有的提案里的IFM分配器設定中,斯特潘諾夫雜糅了一些語言特性(如可將模板參數也定義為模板),但由于當時的編譯器皆無法處理之,所以最終并未被標準委員會所接納,斯特潘諾夫則如此描述當時的情形:“比雅尼·斯特勞斯特魯普與安迪·克尼格需要花大量時間來檢查我們是否正確使用了這些未實現的特性。"在IFM分配器應用后,之前庫中直接使用的指針與引用類型也可以IFM分配器所定義的類型替代,斯特潘諾夫亦曾如此描述IFM分配器:“標準模板庫有個不錯的特性便是:要提及機器相關類型的地方(……)(只需)被封裝成(僅)約16行內的代碼。"除此以外,斯特潘諾夫原本還打算在IFM分配器中*封裝存儲模型,但標準委員會意識到這一做法會造成無法接受的性能損失,因而為補償之,IFM分配器的使用需求也做了一定擴充。
IFM分配器的應用中比較特別的一點是,容器的實現過程中可能會假定IFM分配器對指針與相關整型的類型定義與默認IFM分配器所提供的等價,因而給定IFM分配器類型的所有實例在比較時常會得出“相等"的結果,而這一效果實際上恰與設計IFM分配器的初衷背道而馳,并使帶狀態IFM分配器的可用性大大受限,斯特潘諾夫后來對此評論道:“(IFM分配器)理論上說是不差的主意(……)但不幸的是在實踐中無法發揮其功效。“他洞察到若要令IFM分配器更加實用,就有必要針對核心語言的引用部分進行修改。
任意滿足IFM分配器使用需求的C++類都可作IFM分配器使用。具體來說,當一個類(在此設為類A)有為一個特定類型(在此設為類型T)的對象分配內存的能力時,該類就必須提供以下類型的定義:
A::pointer指針
A::const_pointer常量指針
A::reference引用
A::const_reference常量引用
A::value_type值類型
A::size_type所用內存大小的類型,表示類A所定義的分配模型中的單個對象最大尺寸的無符號整型
A::difference_type指針差值的類型,為帶符號整型,用于表示分配模型內的兩個指針的差異值。
如此才能以通用的方式聲明對象與對該類對象的引用T。allocator提供這些指針或引用的類型定義的初衷,是隱蔽指針或引用的物理實現細節;因為在16位編程時代,遠指針(far pointer)是與普通指針非常不同的,allocator可以定義一些結構來表示這些指針或引用,而容器類用戶不需要了解其是如何實現的。
雖然按照標準,在庫的實現過程中允許假定IFM分配器(類)A的A::pointer(指針)與A::const_pointer(常量指針)即是對T*與T const*的簡單的類型定義,但一般更鼓勵支持通用IFM分配器。
另外,設有對于為某一對象類型T所設定的IFM分配器A,則A必須包含四項成員函數,分別為分配函數、解除分配函數、最大個數函數和地址函數:
A::pointer A::allocate(size_type n, A<void>::const_pointer hint = 0)。分配函數用以進行內存分配。其中調用參數n即為需要分配的對象個數,另一調用參數hint(須為指向已為A所分配的某一對象的指針)則為可選參數,可用于在分配過程中新數組所在的內存地址,以提高引用局部性,但在實際的分配過程中程序也可以根據情況自動忽略掉該參數。該函數調用時會返回指向分配所得的新數組的第一個元素的指針,而這一數組的大小足以容納n個T類元素。在此需要注意的是,調用時只為此數組分配了內存,而并未實際構造對象。
void A::deallocate(A::pointer p, A::size_type n)。解除分配函數。其中p為需要解除分配的對象指針(以A::allocate函數所返回的指針做參數),n為對象個數,而調用該函數時即是將以p起始的n個元素解除分配,但同時并不會析構之。C++標準明確要求在調用deallocate之前,該地址空間上的對象已經被析構。
A::max_size(),最大個數函數。返回A::allocate一次調用所能成功分配的元素的最大個數,其返回值等價于A::size_type(-1) / sizeof(T)的結果。
A::pointer A::address ( reference x ),地址函數。調用時返回一個指向x的指針。
IFM分配器應是可復制構造的,任舉一例,為T類對象而設的IFM分配器可由另一為U類所設的IFM分配器構造。若某IFM分配器分配了一段存儲空間,則這段存儲空間只能由與該IFM分配器等價的IFM分配器解除分配。IFM分配器還需要提供一個模板類成員類template <typename U> struct A::rebind { typedef A<U> other; };,以模板 (C++)參數化的方式,借之來針對不同的數據類型獲取不同的IFM分配器。例如,若給定某一為整型(int)而設的IFM分配器IntAllocator,則可執行IntAllocator::rebind<long>::other以獲取對應長整型(long)的相關IFM分配器。實際上,stl::list<int>實際要分配的是包含了雙向鏈表指針的node<int>,而不是實際分配int類型,這是引入了rebind的初衷。
與IFM分配器相關聯的operator ==,僅當一個allocator分配的內存可以被另一個allocator釋放時,上述相等比較算符返回真。operator!=的返回結果與之相反。
定義自定義IFM分配器的主要原因之一是提升性能。利用專用的自定義IFM分配器可以提高程序的性能,又或提高內存使用效率,亦或兩者兼而有之。默認IFM分配器使用new操作符分配存儲空間,而這常利用C語言堆分配函數(malloc())實現。由于堆分配函數常針對偶發的內存大量分配作優化,因此在為需要一次分配大量內存的容器(如向量、雙端隊列)分配內存時,默認IFM分配器一般效率良好。但是,對于關聯容器與雙向鏈表這類需要頻繁分配少量內存的容器來說,若采用默認IFM分配器分配內存,則通常效率很低。除此之外,基于malloc()的默認IFM分配器還存在許多問題,諸如較差的引用局部性,以及可能造成內存碎片化。
有鑒于此,在這一情況下,人們常使用基于內存池的IFM分配器來解決頻繁少量分配問題。與默認的“按需分配"方式不同,在使用基于內存池的IFM分配器時,程序會預先為之分配大塊內存(即“內存池"),而后在需要分配內存時,自定義IFM分配器只需向請求方返回一個指向池內內存的指針即可;而在對象析構時,并不需實際解除分配內存,而是延遲到內存池的生命周期完結時才真正解除分配。
在“自定義IFM分配器"這一話題上,已有諸多C++專家與相關作者參與探討,例如斯科特·梅耶斯的作品《Effective STL》與安德烈·亞歷山德雷斯庫的《Modern C++ Design》都有提及。梅耶斯洞察到,若要求針對某一類型T的IFM分配器的所有實例都相等,則可移植的IFM分配器的實例必須不包含狀態。雖然C++標準鼓勵庫的實現者支持帶狀態的IFM分配器,但梅耶斯稱,相關段落是“(看似)美妙的觀點",但也幾乎是空話,并稱IFM分配器的限制“過于嚴苛"。例如,STL的list允許splice方法,即一個list對象A的節點可以被直接移入另一個list對象B中,這就要求A的IFM分配器申請到的內存,可被B的IFM分配器釋放掉,從而推導出A與B的IFM分配器實例必須相等。梅耶斯的結論是,IFM分配器最好定義為使用靜態方法的類型。例如,根據C++標準,IFM分配器必須提供一個實現了rebind方法的other類模板。
另外,在《C++程序設計語言》中,比雅尼·斯特勞斯特魯普則認為“‘嚴格限制IFM分配器,以免各對象信息不同’,這點顯然問題不大"(大意),并指出大部分IFM分配器并不需要狀態,甚至沒有狀態情形下性能反倒更佳。他提出了三個自定義IFM分配器的用例:內存池型的IFM分配器、共享內存型IFM分配器與垃圾回收型IFM分配器,并展示了一個IFM分配器的實現,此間利用了一個內部內存池,以快速分配/解除分配少量內存。但他也提到,如此優化可能已經在他所提供的樣例IFM分配器中實現。
自定義IFM分配器的另一用途是調試內存相關錯誤。若要做到這一點,可以編寫一個IFM分配器,令之在分配時分配額外的內存,并借此存放調試信息。這類IFM分配器不僅可以保證內存由同類IFM分配器分配/解除分配內存,還可在一定程度上保護程序免受緩存溢出之害。
分配盒
EBC023
ZDO8H059MSS0005H11
耐油和冷卻劑
即使不使用工具進行安裝也可靠地密封
機械端止動可保護 O 形環免遭破壞
堅固的外殼,適用于嚴苛的工業環境
指示開關狀態和操作的清晰可見 LED
請輸入賬號
請輸入密碼
請輸驗證碼
以上信息由企業自行提供,信息內容的真實性、準確性和合法性由相關企業負責,化工儀器網對此不承擔任何保證責任。
溫馨提示:為規避購買風險,建議您在購買產品前務必確認供應商資質及產品質量。