前言
侯捷的這本《STL源碼剖析》讀本科的時候就拿來膜拜過,但是看不懂。
然后就放棄了,這段時間用STL比較多,上周碰到了一系列問題。
1.需要自定義一個配置器或者自定義一個vector
因為,STL默認的配置器沒有及時釋放內存,當時線上內存使用已超過10g,其中有一半是可以釋放的。
2.使用swap再加上自定義的配置器(使用malloc和free),即便如此進程仍沒有把內存歸還給OS。
通過進一步對比分析,推測很可能是linux中的glibc的緣故,它是管理內存的,介於OS和STL之間。它沒有將內存還給OS。
3.關於map容器的多線程訪問。
理論上STL中的容器,多線程讀應該是安全的,但是實踐中發現使用[]多線程讀map會出現問題,后改用find后就沒問題了。
事實上,我用[]讀map的時候,有的key是不存在的,在這種情況下,我不知道STL會做了什么從而導致了多線程讀出問題。
僅僅知道map的底層是用紅黑樹實現是不夠的。
帶着這些問題我覺的有必要看下這本書。希望通過這次閱讀能知道STL做了什么,書上用的好像是windows下的STL,我搜了下
linux下的STL應該是在bin/usr下面。我這C++的版本是 gcc version 4.4.6 20110731 (Red Hat 4.4.6-3)
還是老習慣,這本書我不會一口氣全看完,具體讀哪些,視情況而定,從第二章開始。另外如果有機會的話,再看下《effect STL》
兩本書都是電子版的,想要的朋友可以聯系我,好了廢話不多說了,開始吧。
第2章 空間配置器(allocator)
2.1.allocator的意義
配置STL中容器的空間,主要指內存,負責申請和釋放。
2.2.allocator的形式
allocator里面有一大堆東西,在不知道需求之前看到這一堆東西是很難理解的。
allocator的重點是allocate,deallocate,construct,destroy 請看一個例子:

1 StlAllocator 2 template<typename Type> 3 class StlAllocator 4 { 5 public: 6 typedef Type value_type; 7 typedef value_type* pointer; 8 typedef const value_type* const_pointer; 9 typedef value_type& reference; 10 typedef const value_type& const_reference; 11 typedef std::size_t size_type; 12 typedef std::ptrdiff_t difference_type; 13 public: 14 template<typename U> 15 struct rebind 16 { 17 typedef StlAllocator<U> other; 18 }; 19 public: 20 inline StlAllocator() {} 21 inline ~StlAllocator() {} 22 inline StlAllocator(StlAllocator const&) {} 23 template<typename U> 24 inline StlAllocator(StlAllocator<U> const&) {} 25 inline pointer address(reference r) { return &r; } 26 inline const_pointer address(const_reference r) { return &r; } 27 inline pointer allocate( size_type cnt, typename std::allocator<void>::const_pointer = 0 ) 28 { 29 return (pointer) malloc( cnt * sizeof(Type) ); 30 } 31 inline void deallocate( pointer p, size_type size ) 32 { 33 free(p); 34 } 35 inline size_type max_size() const 36 { 37 return std::numeric_limits<size_type>::max() / sizeof(Type); 38 } 39 inline void construct(pointer p, const Type& t) { new(p) Type(t); } 40 inline void destroy(pointer p) { p->~Type(); } 41 inline bool operator==(StlAllocator const&) const { return true; } 42 inline bool operator!=(StlAllocator const& a) const { return !operator==(a); } 43 };
書上講了很多,總體上就是內置的配置器有兩種內存申請方式。
1.申請的內存大於128B,此時用的是普通的malloc和free
2.其它的從一個特殊的鏈表上獲取,鏈表上掛着不同大小的可利用內存塊,這些塊是從內存池中獲取的,內存池是事前分配的,不夠了會向系統再申請。
對於方式1,free了以后就釋放了,對於方式2,釋放了以后是還給了這個特殊的鏈表。
感興趣的可以實踐下,構造一個vector< vector<char> >,更改里面的vector長度,代碼如下:
1 #include <vector> 2 #include <iostream> 3 #include <ctime> 4 using namespace std; 5 6 int main() 7 { 8 vector< vector<char> > data; 9 data.resize(1000000); 10 for (int i = 0 ;i < data.size(); i ++) 11 data[i].resize(120); 12 13 cout << "release befor" << endl; 14 sleep(10); 15 vector< vector<char> >().swap(data); 16 cout << "release after" << endl; 17 sleep(10); 18 return 0; 19 }
無論外面的vector多大,能不能釋放還是里面的vector大小決定的