【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 的內存分配和釋放是以對象爲單位,而不是字節。而且內存在釋放的時候,還需要具體指定釋放的內存塊的大小(以對象爲單位)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章