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

  • 相关阅读:
    在Intellij idea 2017中运行tomcat 8.5
    Servlet技术之服务器的安装和配置
    Servlet&&Jsp 概述
    linux 下 tomcat 安装
    执行数据库的更新操作
    JDBC
    Mysql 命令
    hdoj2036 改革春风吹满地——叉积
    常规设置
    pytorch本地安装
  • 原文地址:https://www.cnblogs.com/2010Freeze/p/2647095.html
Copyright © 2020-2023  润新知