SGI list内存管理分析

2013年5月1日 由 Creater 留言 »

list默认使用alloc作为空间配置器,alloc是什么?可以参考前面的文章,其实在这里可能是第一级空间配置器,也可能是第二级空间配置器。

template
class list {};

还是那样为了满足标准,需要对配置器包装,在list中成为list_node_allocator.

  typedef simple_alloc<list_node, Alloc> list_node_allocator;

所以list中就使用list_node_allocator作为配置器。可以如下使用:

list_node_allocator::allocate();
list_node_allocator::deallocate(p)

下面来看看list中节点的构造。
首先看如何配置一个节点空间,并传回地址:

 link_type get_node() { return list_node_allocator::allocate(); }1
再来看如果释放一个节点空间:
1 void put_node(link_type p) { list_node_allocator::deallocate(p); }

那么在list中,如何来构造一个list节点,首先配置空间,然后在返回的空间上构造。

  link_type create_node(const T& x) {
    link_type p = get_node();
    __STL_TRY {
      construct(&p->data, x);
    }
    __STL_UNWIND(put_node(p));
    return p;
  

如何啦析构一个list节点,首先调用析构函数销毁在该内存中的对象,再释放该空间。

  void destroy_node(link_type p) {
    destroy(&p->data);
    put_node(p);
  

注意其中的:construct,destroy这两个全局函数。可以点击这里

list的构造函数比较多

 
list() { empty_initialize(); 
}
list(size_type n, const T& value) { fill_initialize(n, value); }
  list(int n, const T& value) { fill_initialize(n, value); }
  list(long n, const T& value) { fill_initialize(n, value); }
  explicit list(size_type n) { fill_initialize(n, T()); }

#ifdef __STL_MEMBER_TEMPLATES
  template <class InputIterator>
  list(InputIterator first, InputIterator last) {
    range_initialize(first, last);
  }

#else /* __STL_MEMBER_TEMPLATES */
  list(const T* first, const T* last) { range_initialize(first, last); }
  list(const_iterator first, const_iterator last) {
    range_initialize(first, last);
  }
#endif /* __STL_MEMBER_TEMPLATES */
  list(const list<T, Alloc>& x) {
    range_initialize(x.begin(), x.end());
  }

当我们使用list mylist;定义一个list的时候,调用的构造函数为

list() { empty_initialize(); }

这个就产生了只有一个空白节点的list,该节点的前驱和后继都指向自己。

另外所有的构造函数无外乎都都是调用fill_initialize与range_initialize

 void fill_initialize(size_type n, const T& value) {
    empty_initialize();
    __STL_TRY {
      insert(begin(), n, value);
    }
    __STL_UNWIND(clear(); put_node(node));
  }

#ifdef __STL_MEMBER_TEMPLATES
  template <class InputIterator>
  void range_initialize(InputIterator first, InputIterator last) {
    empty_initialize();
    __STL_TRY {
      insert(begin(), first, last);
    }
    __STL_UNWIND(clear(); put_node(node));
  }
#else  /* __STL_MEMBER_TEMPLATES */
  void range_initialize(const T* first, const T* last) {
    empty_initialize();
    __STL_TRY {
      insert(begin(), first, last);
    }
    __STL_UNWIND(clear(); put_node(node));
  }
  void range_initialize(const_iterator first, const_iterator last) {
    empty_initialize();
    __STL_TRY {
      insert(begin(), first, last);
    }
    __STL_UNWIND(clear(); put_node(node));
  }
#endif /* __STL_MEMBER_TEMPLATES */

可以看出,除了默认构造函数外的所有的构造函数都最终调用insert函数来插入初始化,insert有多重重载方式。

广告位

发表评论

你必须 登陆 方可发表评论.