STL深入剖析——————第二章:空间配置器
2014-05-12 16:10
411 查看
本章主要是空间配置器,一般我们都不用管的。不过弄懂这个对接下来的很多内容都可以搞懂,这个还可以提高STL的效率。
下面是allocator的必要接口:
allocator::value_type
allocator::pointer
allocator::const_pointer
allocator::reference
allocator::const_reference
allocator::size_type
allocator::difference_type
allocator::rebind
allocator::allocator()
allocator::allocator(const allocator&)
template<class U>allocator::allocator(const allocator<U>&)
allocator::~allocator()
pointer allocator::address(reference x)const
const_pointer allocator::address(const_reference x)const
pointer allocator::allocate(size_tyoe n, const void* = 0)
void allocator::deallocate(pointer p, size_type n)
size_type allocator::max_size() const
void allocator::construct(pointer p, const T& x)
void allocator::destroy(pointer p)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
根据上面的接口设计一个简单的控件配置器
生成两个文件jjalloc.h和main.cpp
////////////////////////////////
jjalloc.h
#pragma once
#include <new>
#include <cstddef>
#include <cstdlib>
#include <climits>
#include <iostream>
namespace JJ
{
template <class T>
inline T* _allocate(ptrdiff_t size, T*)
{
set_new_handler(0);
T* tmp = (T*)(::operator new ((size_t)(size * sizeof(T))));
if (tmp == 0)
{
cerr << "out of memory" << endl;
exit(1);
}
return tmp;
}
template <class T>
inline void _deallocate(T* buffer)
{
::operator delete(buffer);
}
template <class T1, class T2>
inline void _construct(T1* p, const T2& value)
{
new(p) T1(value);
}
template <class T>
inline void _destroy(T* ptr)
{
ptr->~T();
}
template <class T>
class allocator
{
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
template <class U>
struct rebind
{
typedef allocator<U> other;
};
allocator()
{
return;
}
template <class U>
allocator(const allocator<U>& c)
{
}
pointer allocate(size_type n, const void* hint = 0)
{
return _allocate((difference_type)n, (pointer)0);
}
void deallocate(pointer p, size_type n)
{
_deallocate(p);
}
void construct(pointer p, const T& value)
{
_construct(p, value);
}
void destroy(pointer p)
{
_destroy(p);
}
pointer address(reference x)
{
return (pointer)&x;
}
const_pointer const_address(const_reference x)
{
return (const_pointer)&x;
}
size_type max_size() const
{
return size_type(UINT_MAX/sizeof(T));
}
};
}
/////////////////////////////////////////////////////
main.cpp的
#include "jjalloc.h"
#include <vector>
#include <iostream>
using namespace std;
int main()
{
int ia[5] = {0, 1, 2 ,3 ,4};
unsigned int i;
vector<int, JJ::allocator<int>> iv(ia, ia + 5);
for (i = 0; i < iv.size(); i++)
{
cout << iv[i] << endl;
}
}
以上代码为了在VS2010下面运行,在源代码的基础上加上了拷贝构造函数。
下面我就浅要的分析一下这段代码的含义吧。
先介绍一下,基本上很少用到的函数。
set_new_handler函数:当运算符找不到足够大的连续内存来为对象分配内存时调用这个函数。会自动抛出异常。
这段代码简单的构建出了一个容器的基本框架。容器的基本写法就是用泛函数写的。大量的template。allocator类
主要应用与容器的内存管理。在分配对象时,从这个池来获取,而不是使用new。在某种情况下,这种高度自定义的
内存管理能极大地提高程序效率。
STL标准规格告诉我们。配置器定义于<memory>之中
#include<stl_alloc.h> //负责内存空间的配置与释放
#include<stl_construct.h> //负责对象内容的构造与析构
std::alloc设计思想如下:
1.向system heap要求空间
2.考虑多线程状态
3.考虑内存不足时的应变措施
4.考虑过多"小型区块"可能造成的内存碎片问题
第一级配置器直接使用malloc()和free(),第二级配置器则视情况采用不同的策略:当配置区块超过128bytes时,视之为“足够大”,便调用第一级配置器。
当配置区块小于128bytes时,视之为"过小",为了降低额外负担,便采用复杂的memory pool整理方式。
汗,写到这里感觉有点照本宣科的意思~。自己也感觉一知半解。不过总的来说就是属于内存分配这部分。
看了这一部分的内容。感觉可以用这个来做消息队列。
下面是allocator的必要接口:
allocator::value_type
allocator::pointer
allocator::const_pointer
allocator::reference
allocator::const_reference
allocator::size_type
allocator::difference_type
allocator::rebind
allocator::allocator()
allocator::allocator(const allocator&)
template<class U>allocator::allocator(const allocator<U>&)
allocator::~allocator()
pointer allocator::address(reference x)const
const_pointer allocator::address(const_reference x)const
pointer allocator::allocate(size_tyoe n, const void* = 0)
void allocator::deallocate(pointer p, size_type n)
size_type allocator::max_size() const
void allocator::construct(pointer p, const T& x)
void allocator::destroy(pointer p)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
根据上面的接口设计一个简单的控件配置器
生成两个文件jjalloc.h和main.cpp
////////////////////////////////
jjalloc.h
#pragma once
#include <new>
#include <cstddef>
#include <cstdlib>
#include <climits>
#include <iostream>
namespace JJ
{
template <class T>
inline T* _allocate(ptrdiff_t size, T*)
{
set_new_handler(0);
T* tmp = (T*)(::operator new ((size_t)(size * sizeof(T))));
if (tmp == 0)
{
cerr << "out of memory" << endl;
exit(1);
}
return tmp;
}
template <class T>
inline void _deallocate(T* buffer)
{
::operator delete(buffer);
}
template <class T1, class T2>
inline void _construct(T1* p, const T2& value)
{
new(p) T1(value);
}
template <class T>
inline void _destroy(T* ptr)
{
ptr->~T();
}
template <class T>
class allocator
{
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
template <class U>
struct rebind
{
typedef allocator<U> other;
};
allocator()
{
return;
}
template <class U>
allocator(const allocator<U>& c)
{
}
pointer allocate(size_type n, const void* hint = 0)
{
return _allocate((difference_type)n, (pointer)0);
}
void deallocate(pointer p, size_type n)
{
_deallocate(p);
}
void construct(pointer p, const T& value)
{
_construct(p, value);
}
void destroy(pointer p)
{
_destroy(p);
}
pointer address(reference x)
{
return (pointer)&x;
}
const_pointer const_address(const_reference x)
{
return (const_pointer)&x;
}
size_type max_size() const
{
return size_type(UINT_MAX/sizeof(T));
}
};
}
/////////////////////////////////////////////////////
main.cpp的
#include "jjalloc.h"
#include <vector>
#include <iostream>
using namespace std;
int main()
{
int ia[5] = {0, 1, 2 ,3 ,4};
unsigned int i;
vector<int, JJ::allocator<int>> iv(ia, ia + 5);
for (i = 0; i < iv.size(); i++)
{
cout << iv[i] << endl;
}
}
以上代码为了在VS2010下面运行,在源代码的基础上加上了拷贝构造函数。
下面我就浅要的分析一下这段代码的含义吧。
先介绍一下,基本上很少用到的函数。
set_new_handler函数:当运算符找不到足够大的连续内存来为对象分配内存时调用这个函数。会自动抛出异常。
这段代码简单的构建出了一个容器的基本框架。容器的基本写法就是用泛函数写的。大量的template。allocator类
主要应用与容器的内存管理。在分配对象时,从这个池来获取,而不是使用new。在某种情况下,这种高度自定义的
内存管理能极大地提高程序效率。
STL标准规格告诉我们。配置器定义于<memory>之中
#include<stl_alloc.h> //负责内存空间的配置与释放
#include<stl_construct.h> //负责对象内容的构造与析构
std::alloc设计思想如下:
1.向system heap要求空间
2.考虑多线程状态
3.考虑内存不足时的应变措施
4.考虑过多"小型区块"可能造成的内存碎片问题
第一级配置器直接使用malloc()和free(),第二级配置器则视情况采用不同的策略:当配置区块超过128bytes时,视之为“足够大”,便调用第一级配置器。
当配置区块小于128bytes时,视之为"过小",为了降低额外负担,便采用复杂的memory pool整理方式。
汗,写到这里感觉有点照本宣科的意思~。自己也感觉一知半解。不过总的来说就是属于内存分配这部分。
看了这一部分的内容。感觉可以用这个来做消息队列。
相关文章推荐
- 带你深入理解STL之空间配置器(思维导图+源码)
- 带你深入理解STL之空间配置器(思维导图+源码)
- 《STL 源码剖析》之空间配置器
- STL源码剖析学习笔记之具备次配置力(sub-allocation)的SGI空间配置器
- STL深入探究(一、空间配置器)
- C++STL学习(13)STL深入(2) SGI STL空间配置器
- STL学习_SGI二级空间配置器源码剖析
- STL源码剖析学习二:空间配置器(allocator)
- STL之空间配置器源码(框架)剖析
- STL 源码剖析读书笔记一:空间配置器
- STL空间配置器——第二级配置器__default_alloc_template剖析
- 【STL深入学习】SGI STL空间配置器详解(二)-第二级空间配置器
- STL空间配置器——第一级配置器__malloc_alloc_template剖析
- STL中的空间配置器allocator的实现原理及源码剖析
- 【STL深入学习】SGI STL空间配置器详解(一)-第一级空间配置器
- 【STL】空间配置器(二):二级空间配置器
- STL学习笔记之空间配置器
- 一步一步写STL:多级空间配置器(上)
- STL中空间配置器的策略
- STL源码分析--空间配置器的底层实现 (二)