简单的空间配置器实现

这一节用到的小知识:

1.ptrdirr_t:

ptrdiff_t是C/C++标准库中定义的一个与机器相关的数据类型。ptrdiff_t类型变量通常用来保存两个指针减法操作的结果。ptrdiff_t定义在stddef.h(cstddef)这个文件内。ptrdiff_t通常被定义为long int类型。

2.non-trivial constructor/destructor:

意思是“非默认构造函数/析构函数”,这里的non-trivial指不是编译器自动生成的(函数)维基百科

我认为trivial更深层次的含义是构造和析构的东西都是在栈上分配的,其内存可以被栈自动回收,所以SGI
STL的空间配置器std::alloc在做destroy时会先判断析构对像是不是trivial,如果对象是trivial,证明对象的所有成员分配在栈上,那么为了节省效率,可以不调用析构函数,由栈来自动回收内存。如果对象是non-trivial则需要调用每个对象的析构函数,释放堆上分配的内存。

3.operator
new():

指对new的重载形式,它是一个函数,并不是运算符。对于operator new来说,分为全局重载和类重载,全局重载是void* ::operator new(size_t size),在类中重载形式 void* A::operator
new(size_t size)。还要注意的是这里的operator new()完成的操作一般只是分配内存,事实上系统默认的全局::operator new(size_t size)也只是调用malloc分配内存,并且返回一个void*指针。而构造函数的调用(如果需要)是在new运算符中完成的。

4.由第三点可知,在空间配置器的new操作分为两步:allocate()函数分配内存,construct()函数把分配的内存初始化为一个个的模板类对象。

侯捷老师的书中介绍了空间配置器基本的接口(p43~44)。以下是一个简单的空间配置器实现:

cghAlloc.h:

#ifndef _CGH_ALLOC
#define _CGH_ALLOC

#include <new>
#include <cstddef>
#include <cstdlib>
#include <climits>
#include <iostream>

namespace CGH
{
	template<class T>
	inline T* _allocate(ptrdiff_t size, T*)
	{
		set_new_handler(0);
		T* tmp = (T*)(::operator new((size_t)(size * sizeof(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); // 调用placement new,在指定的内存位置p处初始化T1对象,初始化T1对象时调用T1的复制构造函数
	}

	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;
		};

		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));
		}
	};
}

#endif

测试空间配置器

allocator.cpp:

// allocator.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "cghAlloc.h"
#include <vector>
#include <iostream>
using namespace::std;

int _tmain(int argc, _TCHAR* argv[])
{
	int arr[5] = { 0, 1, 2, 3, 4 };
	//unsigned int i;
	CGH::allocator<int> test;
	CGH::allocator<int> test1;

	vector<int, CGH::allocator<int>>iv(arr, arr + 5);
	for (int i = 0; i < iv.size(); i++){
		cout << iv[i] << ' ';
	}
	cout << endl;
	system("pause");
	return 0;
}
时间: 2024-10-08 07:02:42

简单的空间配置器实现的相关文章

STL初探——设计一个简单的空间配置器

#pragma once #ifndef _M_ALLOCATOR #define _M_ALLOCATOR #include <new> //用于定向开辟内存 #include <cstddef> //用于存储中间量的类型,ptrdiff_t和size_t #include <cstdlib> //exit() #include <climits> //UINT_MAX #include <iostream> //cerr namespace

STL源码剖析 — 空间配置器(allocator)

前言 以STL的实现角度而言,第一个需要介绍的就是空间配置器,因为整个STL的操作对象都存放在容器之中. 你完全可以实现一个直接向硬件存取空间的allocator. 下面介绍的是SGI STL提供的配置器,配置的对象,是内存.(以下内容来自<STL源码剖析>) 空间配置器的标准接口 根据STL的规范,allocator的必要接口 各种typedef 1 allocator::value_type 2 allocator::pointer 3 allocator::const_pointer 4

2.1 空间配置器(allocator)

空间配置器隐藏在一切组件之后. 1.1 设计一个简单的空间配置器 根据STL的规范,以下是allocator的必要接口: allocator::value_type allocator::pointer allocator::const_pointer allocator::reference allocator::const_reference allocator::size_type allocator::difference_type allocator::rebind // 一个嵌套的(

STL学习笔记--2、空间配置器 allocator

2.1标准接口 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 allo

STL空间配置器那点事

STL简介 STL(Standard Template Library,标准模板库),从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合. 谈及组件,那么我们就首先来简单谈下STL六大组件,其相关的设计模式使用,以及各组件之间的协作关系. 设计模式一览 六大组件简单介绍 1. 空间配置器:内存池实现小块内存分配,对应到设计模式--单例模式(工具类,提供服务,一个程序只需要一个空间配置器即可),享元模式(小块内存统一由

SGI的特殊空间配置器

SGI的空间配置器allocator只是简单的new和delete的一层包装,没有提供效率的强化. 而一般C++内存配置和释放操作如下: class  Foo  { ... } Foo  *pf = new Foo; delete pf; new算式:1)使用new配置内存,2)使用Foo构造对象 delelte算式: 1)使用~Foo()将对象析构 ,2)使用delete释放内存 STL allocator 将这两阶段操作区分开来.内存配置操作由 alloc::allocate() 负责,内存

STL源码剖析 --- 空间配置器 std::alloc

STL是建立在泛化之上的.数组泛化为容器,参数化了所包含的对象的类型.函数泛化为算法,参数化了所用的迭代器的类型.指针泛化为迭代器,参数化了所指向的对象的类型.STL中的六大组件:容器.算法.迭代器.配置器.适配器.仿函数. 这六大组件中在容器中分为序列式容器和关联容器两类,正好作为STL源码剖析这本书的内容.迭代器是容器和算法之间的胶合剂,从实现的角度来看,迭代器是一种将operator*.operator->.operator++.operator-等指针相关操作予以重载的class tem

stl空间配置器线程安全问题补充

摘要 在上一篇博客<STL空间配置器那点事>简单介绍了空间配置器的基本实现 两级空间配置器处理,一级相关细节问题,同时简单描述了STL各组件之间的关系以及设计到的设计模式等. 在最后,又关于STL空间配置的效率以及空间释放时机做了简单的探讨. 线程安全问题概述 为什么会有线程安全问题? 认真学过操作系统的同学应该都知道一个问题. first--进程是系统资源分配和调度的基本单位,是操作系统结构的基础,是一个程序的运行实体,同时也是一个程序执行中线程的容器 seconed--进程中作为资源分配基

STL源码剖析--空间配置器

STL的设计非常巧妙,组件间互取短长,形成了一个世界,这是这个世界里的组件: 1. containers(容器):所谓容器,是指存放数据的地方,将数据以一定的方法组织存放.根据不同的组织方式,可以把容器分为顺序容器,如vector.deque.list,关联容器,如set.map.Container是一种class template. 2. algorithm(算法):各种常用不常用的算法如sort.copy.search等等.algorithm是一种function template. 3.