C++ STL: 分配器allocators 源码分析
STL 基本的六大組件作用以及功能如下:
可以看到allocator是數據存儲組件container的幕后支持者,負責為其數據存儲分配對應的存儲空間。
operator::new
在詳細介紹alloctor之前,先描述一下new運算符,我們使用C++ new一個對象的時候就是調用底層operator::new運算符,實現如下:
void * operator new(std::size_t size)
{++allocations;void * retval = malloc(size);if (!retval)throw std::bad_alloc();return retval;
}
可以看到底層仍然是調用 C 語言的庫函數 malloc進行對應存儲空間的分配,分配的大小就是我們傳入的size,總共size 個bytes的大小。
這里再簡單描述一下malloc分配指定size大小的內存空間分布情況如下:`
可以看到這里malloc分配的物理內存占用實際上還有一些頭部和尾部用來對當前內存空間進行管理。
分配器 Allocators
在STL的容器中,基本都會使用相同的allocator函數進行對應內存空間的分配,如下:
接下來可以看一下對應allocator類的實現:
其中allocate函數的實現如下:
可以看到底層調用的還是operator new操作符,同時對應的deallocate函數的底層釋放仍然調用的是operator delete,綜上從源碼的實現上我們可以知道allocator底層仍然調用的是malloc和free進行對應空間的分配和釋放。
我們代碼中的空間分配和釋放 過程可以編寫如下代碼:
//分配空間,一下allocate的方式是初始化了一個臨時對象,調用對應的allocate函數
int *p = allocator<int>().allocate(512,(int*)0);
// 在的釋放的時候調用對應的deallocate函數
allocator<int>().deallocate(p,512);
在GNU 2.9-4.9版本之間發生過一些變更
GNU2.9的 defalloc.h關于allocate和deallocate函數的實現如下:
看得出來以上都是基于operator new和operator delete進行的封裝, 且沒有增加自己的設計。
但是2.9版本的并不推薦使用Allocator的實現,想要提升性能,對內存空間有更加合理的管理,所以他們在容器中使用的是自封裝的alloc類的實現(stl_alloc.h)。
邏輯結構圖如下:
但是到了GNU4.9 版本之后,allocator的實現又恢復到未經任何封裝的new/delete 運算符的實現了。
當然在4.9之中,也實現了其他的allocator,比如:__pool_alloc
我們可以在分配空間的時候自己進行指定調用
vector<string,__gnu_cxx::__pool_alloc<string>> vec;
總結
以上是生活随笔為你收集整理的C++ STL: 分配器allocators 源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 看着我看着你是哪首歌啊?
- 下一篇: 大家帮我看看宋茜背的这个包包是什么牌子,