VS 2010 STL 内存分配器

本文深入探讨了C++中内存管理的关键概念,包括分配(Alloc)、构造(Construct)、析构(Destroy)和释放(DeAlloc)。通过分析内联模板函数的具体实现,如_Allocate、_Construct、_Destroy和分配器类_ALLOCATOR,揭示了这些操作背后的机制。特别关注了分配器如何替代new和delete操作符,以及其在不同类型的对象构造和销毁中的应用。

Alloc是分配内存之意,Construct是在内存里构造之意。就好C++里的new有分配内存,在分配的内存里构造我们的对象这两层作用。 其实这也就是分配器的作用。替换new与delete。

// TEMPLATE FUNCTION _Allocate
template<class _Ty> inline
	_Ty _FARQ *_Allocate(_SIZT _Count, _Ty _FARQ *)
	{	// allocate storage for _Count elements of type _Ty
	void *_Ptr = 0;

	if (_Count <= 0)
		_Count = 0;
	else if (((_SIZT)(-1) / sizeof (_Ty) < _Count)
		|| (_Ptr = ::operator new(_Count * sizeof (_Ty))) == 0)
		_THROW_NCEE(bad_alloc, 0);

	return ((_Ty _FARQ *)_Ptr);
	}
		// TEMPLATE FUNCTION _Construct
template<class _Ty1,
	class _Ty2> inline
	void _Construct(_Ty1 _FARQ *_Ptr, _Ty2&& _Val)
	{	// construct object at _Ptr with value _Val
	void _FARQ *_Vptr = _Ptr;
    //placement new
	::new (_Vptr) _Ty1(_STD forward<_Ty2>(_Val));
	}

template<class _Ty1> inline
	void _Construct(_Ty1 _FARQ *_Ptr)
	{	// construct object at _Ptr with default value
	void _FARQ *_Vptr = _Ptr;
    //placement new
	::new (_Vptr) _Ty1();
	}

Desotry是析构之意,可不是删除内存啊。删除内存对应的是DeAlloc。 

// TEMPLATE FUNCTION _Destroy
template<class _Ty> inline
	void _Destroy(_Ty _FARQ *_Ptr)
	{	// destroy object at _Ptr
	_Ptr->~_Ty();
	}

//特化
template<> inline
	void _Destroy(char _FARQ *)
	{	// destroy a char (do nothing)
	}

//特化
template<> inline
	void _Destroy(wchar_t _FARQ *)
	{	// destroy a wchar_t (do nothing)
	}

 #ifdef _NATIVE_WCHAR_T_DEFINED
//特化
template<> inline
	void _Destroy(unsigned short _FARQ *)
	{	// destroy a unsigned short (do nothing)
	}
 #endif /* _NATIVE_WCHAR_T_DEFINED */

 反正牛逼的代码总喜欢搞一个基类,搞基就对了。

		// TEMPLATE CLASS _Allocator_base
template<class _Ty>
	struct _Allocator_base
	{	// base class for generic allocators
	typedef _Ty value_type;
	};

//const _Ty为啥要单独分出来呢,欲意何为
		// TEMPLATE CLASS _Allocator_base<const _Ty>
template<class _Ty>
	struct _Allocator_base<const _Ty>
	{	// base class for generic allocators for const _Ty
	typedef _Ty value_type;
	};

正题来了: 

		// TEMPLATE CLASS _ALLOCATOR
template<class _Ty>
	class _ALLOCATOR
		: public _Allocator_base<_Ty>
	{	// generic allocator for objects of class _Ty
public:
	typedef _Allocator_base<_Ty> _Mybase;
	typedef typename _Mybase::value_type value_type;

	typedef value_type _FARQ *pointer;
	typedef value_type _FARQ& reference;
	typedef const value_type _FARQ *const_pointer;
	typedef const value_type _FARQ& const_reference;

	typedef _SIZT size_type;
	typedef _PDFT difference_type;

    //这个rebind真的是非常之重要。它是什么个意思呢。比如本来_ALLOCATOR<int>,那么这个分配器以    
    //int型来分配内存,结果现在
    //typename _ALLOCATOR<int>::template rebind<_Container_proxy>::other Al;
    //那么Al就是以_Container_proxy型来分配内存的了。
	template<class _Other>
		struct rebind
		{	// convert this type to _ALLOCATOR<_Other>
		typedef _ALLOCATOR<_Other> other;
		};

	pointer address(reference _Val) const
		{	// return address of mutable _Val
		return ((pointer) &(char&)_Val);
		}

	const_pointer address(const_reference _Val) const
		{	// return address of nonmutable _Val
		return ((const_pointer) &(char&)_Val);
		}

	_ALLOCATOR() _THROW0()
		{	// construct default allocator (do nothing)
		}

	_ALLOCATOR(const _ALLOCATOR<_Ty>&) _THROW0()
		{	// construct by copying (do nothing)
		}

	template<class _Other>
		_ALLOCATOR(const _ALLOCATOR<_Other>&) _THROW0()
		{	// construct from a related allocator (do nothing)
		}

	template<class _Other>
		_ALLOCATOR<_Ty>& operator=(const _ALLOCATOR<_Other>&)
		{	// assign from a related allocator (do nothing)
		return (*this);
		}

    //释放内存,这里调用的是::operator delete,delete的只释放内存的那部分功能
	void deallocate(pointer _Ptr, size_type)
		{	// deallocate object at _Ptr, ignore size
		::operator delete(_Ptr);
		}

	pointer allocate(size_type _Count)
		{	// allocate array of _Count elements
		return (_Allocate(_Count, (pointer)0));
		}

	pointer allocate(size_type _Count, const void _FARQ *)
		{	// allocate array of _Count elements, ignore hint
		return (allocate(_Count));
		}

	void construct(pointer _Ptr, const _Ty& _Val)
		{	// construct object at _Ptr with value _Val
		_Construct(_Ptr, _Val);
		}

	void construct(pointer _Ptr, _Ty&& _Val)
		{	// construct object at _Ptr with value _Val
		::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Ty>(_Val));
		}

	template<class _Other>
		void construct(pointer _Ptr, _Other&& _Val)
		{	// construct object at _Ptr with value _Val
		::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Other>(_Val));
		}

    //析构对象
	void destroy(pointer _Ptr)
		{	// destroy object at _Ptr
		_Destroy(_Ptr);
		}

    //(_SIZT)(-1)其实就是那个最大的unsigned int
	_SIZT max_size() const _THROW0()
		{	// estimate maximum array size
		_SIZT _Count = (_SIZT)(-1) / sizeof (_Ty);
		return (0 < _Count ? _Count : 1);
		}
	};

 

C++ STL 中的空间分配器(Allocator)是一种用于抽象和管理内存分配与释放的机制,广泛应用于标准模板库(STL)容器中。它的主要作用是为容器提供高效的内存管理策略,确保容器能够按需动态分配和释放内存[^1]。分配器的设计允许开发者自定义内存管理策略,从而优化性能、满足特殊需求或实现特定功能(如内存池、共享内存等)。 ### 原理 STL 提供了默认的分配器 `std::allocator`,它是一个类模板,用于为容器分配和释放内存。`std::allocator` 的实现通常基于操作系统的内存分配函数,如 `malloc` 和 `free`。然而,SGI STL 实现中引入了更为高效的内存管理策略,即空间配置器(Memory Allocator)。 SGI STL 的空间配置器主要分为两个级别: 1. **一级空间配置器**:直接使用 `malloc` 和 `free` 进行内存分配与释放。适用于大块内存的分配。 2. **二级空间配置器**:针对小块内存进行了优化,采用内存池(Memory Pool)技术。通过维护一个自由链表(Free List)来管理多个固定大小的小块内存,从而减少内存碎片并提高分配效率[^5]。 在 SGI STL 的二级空间配置器中,内存分配流程如下: - 如果请求的内存大小大于某个阈值(通常为 128 字节),则直接使用一级空间配置器进行分配。 - 如果请求的内存小于等于该阈值,则根据内存块大小选择对应的自由链表进行分配。如果自由链表中有可用内存块,则直接返回;如果没有,则批量申请多个内存块并加入自由链表,然后返回一个[^5]。 ### 使用 在 STL 容器中,分配器通常作为模板参数传入。例如,`std::vector` 的定义如下: ```cpp template <class T, class Allocator = std::allocator<T>> class vector; ``` 默认情况下,`std::vector` 使用 `std::allocator` 作为其分配器。如果需要自定义分配器,可以通过模板参数传入自定义的分配器类。例如,定义一个使用自定义分配器的 `vector`: ```cpp template <class T> class MyAllocator { public: // 分配器接口 T* allocate(size_t n) { return static_cast<T*>(::operator new(n * sizeof(T))); } void deallocate(T* p, size_t n) { ::operator delete(p); } // 其他必要的成员函数 }; std::vector<int, MyAllocator<int>> vec; ``` 上述代码中,`MyAllocator` 是一个简单的自定义分配器,它实现了 `allocate` 和 `deallocate` 方法来管理内存。通过将 `MyAllocator` 作为模板参数传递给 `std::vector`,可以覆盖默认的内存管理策略[^2]。 ### 相关问题 1. 如何实现一个自定义的 C++ STL 分配器? 2. C++ STL 中的一级空间配置器和二级空间配置器有什么区别? 3. 为什么在 C++ STL 中使用内存池技术可以提高内存分配效率? 4. 如何在实际项目中优化 C++ STL 容器的内存使用? 5. C++ STL 分配器如何影响容器的性能?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值