C 中為什麼要有allocator類?

時間 2021-05-30 20:21:17

1樓:Wu Jarvis

我是這麼理解的:其實你只要分清vector中resize,reserve的關係就能明白了,resize時,當元素數量》capacity時不但會分配空間,而且會初始化元素;reserve只會做分配空間的事情,不會做初始化,這樣就把分配空間和初始化的事情分開來了,如果不分開的話,那麼在reserve分配空間時就會初始化,然後在使用元素的時候還需要再初始化一次,這樣就造成了初始化的浪費。

2樓:斯圖亞特

雖然我也一直沒想通為什麼要有allocator類,但你提問的質疑我也沒有看懂。

我理解你那句話裡的記憶體分配的開銷主要不是指管OS要一塊虛擬記憶體或OS分配一塊物理記憶體的開銷,而是從虛擬記憶體裡劃一塊記憶體給特定的物件。經常是一小塊。所以一塊一塊小物件分配,還是批量分配一大堆,開銷還是不一樣的。

所以說這句話在邏輯上還是說得通的。

3樓:

看了各位大神的回答,我想提一句stl還是有些歷史的,90年代初期就有cpp的stl,當然那時候cpp還沒標準化罷了,那個時候有far near pointer的破事,處理器的鍋,所以引入個這玩意兒也不全然是為了抽象啊什麼的,還有就是隔離這些細節。

4樓:陳厚來

回答題主的問題,簡單一句話,allocator又是c++的乙個糟糕的設計,不要也罷。

為什麼這麼說呢?allocator的目的,就是給容器的使用者乙個機會,選擇用自己的分配器取代系統預設的。這樣做的好處在於:

在記憶體受限的系統,有目的的決定記憶體的管理方式

如果系統預設分配器做的不夠好,程式設計師還有優化的機會

但是事實上,以上目的真的能達到呢?幾乎不可能。

1. allocator沒有對分配的物件型別和大小做約束,這導致了我要實現乙個allocator,就不得不實現乙個複雜的記憶體分配演算法。於是應用到記憶體受限系統,立刻變得困難重重。

如果c++能夠保證,傳給vector的allocator,只分配固定長度size(T)的記憶體,這樣的allocator就比較有實用價值,很適合記憶體受限系統實現快取池。實際上,完全沒有這樣的保證。使用了allocator,仍無法避免和記憶體碎片和記憶體不足做鬥爭,那麼為什麼還要allocator, 直接用系統new/delete就好。

2. 如果說不信任系統的new/delete,讓程式設計師有優化記憶體分配的機會,還不如直接優化new/delete來的爽快。這個角度看,更加沒必要有allocator.

綜上,allocator的設計決策做的很差,沒有在理想和現實之間做出平衡。這種東西,宜棄之。

5樓:zpan

如果你寫嵌入式程式,特別是像 DSP 等沒有 OS 的裸板程式,就會知道,記憶體分配是個非常棘手的問題。光有 malloc 是不行的。首先有的平台根本就沒有 malloc 可用。

其次,有些平台使用的是哈佛架構,或者甚至有多片不同記憶體的架構,它們往往會提供私有的庫函式來指定從哪一片記憶體上分配,這時 malloc 就不管用了。

還有一種情況就是你需要使用記憶體池來提高程式的實時性,這個對電腦程式也適用。

當然你也可以要求使用者在呼叫你庫的時候自己事先把記憶體分配好,但這顯然對庫的編寫帶來很多麻煩。引入 allocator 就能大大簡化問題,本質上是要求庫的呼叫者去實現一套 malloc。

那麼也就像輪子哥說的那樣。如果用建構函式傳 IAllocator* 的方式,就要通過 dynamic dispatch 的方式去呼叫分配函式。而如果作為模板引數,則呼叫方式是 static dispatch,可以 inline。

C++ 追求 zero cost abstraction,自然會選擇後者。

可能你還會問,就不能整個庫用同乙個 allocator 麼?那這樣顯然是不夠靈活的。輪子哥說的用繼承的方式也同理。

有時候我們還是需要為不同的物件使用不同的 allocator 的。

6樓:「已登出」

我覺得是個錯誤。正確的寫法是

malloc + std::aligned_storage_t> + in-place new。

7樓:sch001

allcator有沒有必要不懂,平時說的資源指的是時空吧。只allocate不construct不用調建構函式。如果是new operator就會把申請記憶體和建構函式一起搞了,而一般情況下你沒那麼快構造,當然operator new可以避免這個問題。。

初學,不妥望見諒

8樓:

C++ Primer說的不是分配記憶體浪費

而是分配記憶體和物件構造組合在一起導致浪費,很多時候記憶體分配和物件構造需要分開進行

9樓:石大頭

像std::vector這種構造時會分配動態記憶體的,所以分配記憶體和構造不一樣。不信你p=malloc(sizeof(std::vector)), 試試p能用不?

10樓:

不是每次構造都會伴隨著記憶體分配。placement new了解一下?

更何況記憶體分配不一定必須要malloc陷入核心,也可以是往記憶體池裡要一塊空間。

所以省的還主要就是分配記憶體需要的資源,而非構造時的資源。

總的來說,分離記憶體分配與物件構造能提供更細粒度的控制,提供了更多節省開銷的途徑。

至於現在allocator的設計合不合理,那是另一回事

11樓:徐若疾

其實原文已經寫的很清楚了:

When we allocate a block of memory, we often plan to construct objects in that

memory as needed. In this case, we』d like to decouple memory allocation from object

construction. Decoupling construction from allocation means that we can allocate

memory in large chunks and pay the overhead of constructing the objects only when

we actually need to create them.

In general, coupling allocation and construction can be wasteful. For example:

然後舉了乙個例子,這個例子我覺得有點不夠直接,但是想要表達的意思是表達到了的,為什麼說會有可能浪費(can be wasteful)是因為記憶體確實是分配了,但是有可能分配的過多了:

This new expression allocates and initializes n strings. However, we might not need

n strings; a smaller number might suffice.

還有就是除了記憶體資源,cpu,快取這些都是資源,分配浪費記憶體,然後構造的時候各種賦值,拷貝還會導致cpu,快取等等資源的浪費,費電:

Moreover, for those objects we do use, we immediately

assign new values over the previously initialized strings. The elements that are used

are written twice: first when the elements are default initialized, and subsequently

when we assign to them.

先是new構造了一次,然後跟著來了一次賦值,浪費了。

然後allocator的作用呢?

lets us separate

allocation from construction. It provides type-aware allocation of raw, unconstructed,

memory

原文還是寫的很清楚的。

c 中明明有vector了為什麼還要有stack?

飛翔的荷蘭豬 作為乙個類的設計者,不僅要考慮類的使用者所需要的的功能,也要考慮如何限制類使用者的不當操作。同樣當需要乙個stack的時候,很有可能下標訪問,中間插入等操作,會影響物件本身功能的時候。要限制這種操作,一是注釋告訴物件使用者,禁止使用下標訪問等操作,當更好的辦法是,從根本上就不提供這樣的...

C 類當中為什麼要有private?

麻辣牛肉 為什麼要有C 到了彙編全都是記憶體位址,暫存器和運算,C不就很好了嗎?還是說直接彙編就ok了?什麼虛函式,引用,const,統統不過是語法糖罷了,到了彙編,還不是乙個樣 Ronaldo 因為private就是要在編譯期間限制你這個類成員只能這個類自己用,其他類別用,也別操心。用了就給你報錯...

Java為什麼要有反射機制,而 C 沒有?

這個語言一開始不是精心設計的,只是為了給C打補丁,後來也是持續的打補丁。語言沒有被一家控制,各個編譯器廠商為所欲為的自己擴充套件語法,想改動點什麼很難。反射是好事,各個編譯器都能輸出符號表,debug工具都支援反射,難度不在於實現,而在於撕逼。 Home RTTR 乙個C 的反射庫,沒用過不知道是否...