【C++内存管理】vs2017 标准分配器实现

vs2017 标准库中,std::allocator 的实现如下:

template<class _Ty>
class allocator
{
//...
	void deallocate(_Ty * const _Ptr, const size_t _Count)
	{	// deallocate object at _Ptr
		// no overflow check on the following multiply; we assume _Allocate did that check
		_Deallocate<_New_alignof<_Ty>>(_Ptr, sizeof(_Ty) * _Count);
	}

	_NODISCARD _DECLSPEC_ALLOCATOR _Ty * allocate(_CRT_GUARDOVERFLOW const size_t _Count)
		{	// allocate array of _Count elements
		return (static_cast<_Ty *>(_Allocate<_New_alignof<_Ty>>(_Get_size_of_n<sizeof(_Ty)>(_Count))));
		}
	}

allocator 是一个模板类,_Ty 用来指定给具体类分配内存。其中最重要的当然是 deallocateallocate 两个函数,用来分配内存和释放内存。


先来看看 allocate

  • 传入的参数为待分配内存对象的个数,而不是字节数。
  • 底层的实现如下:
_DECLSPEC_ALLOCATOR static void * _Allocate(const size_t _Bytes)
{
	return (::operator new(_Bytes));
}

可以看到,它并没有做任何内存管理的动作,只是调用了全局的 operator new 函数。


再来看看 deallocate

  • 传入的参数为待释放内存块的指针,以及其中的放置对象的数量。
  • 底层实现如下:
template<size_t _Align,
	enable_if_t<(!_HAS_ALIGNED_NEW || _Align <= __STDCPP_DEFAULT_NEW_ALIGNMENT__), int> = 0> inline
	void _Deallocate(void * _Ptr, size_t _Bytes)
	{	// deallocate storage allocated by _Allocate when !_HAS_ALIGNED_NEW || _Align <= __STDCPP_DEFAULT_NEW_ALIGNMENT__
	//...
	::operator delete(_Ptr, _Bytes);
	}

可以看到,它也只是调用了全局的 operator delete 函数。


因此,由上可以看出:
  • std::allocator 并没有做任何内存管理的动作,底层只是调用了 ::operator new::operator delete,而它们又底层调用了 mallocfree。所以,cookie 的内存浪费仍然存在。
  • std::allocator 的内存分配和释放是以对象为单位,而不是字节。而且内存在释放的时候,还需要具体指定释放的内存块的大小(以对象为单位)。

你可能感兴趣的:(C++内存管理)