STL源码剖析读书笔记-第2章

前言

侯捷的这本《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 请看一个例子:

StlAllocator
 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大小决定的

 

 

你可能感兴趣的:(读书笔记)