STL 内存池源码学习与思考

首先说明一下,这次学习的是STL空间配置器的源码中内存池部分的函数,下面是源码:
template <bool __threads, int __inst>
char*
__default_alloc_template<__threads, __inst>::_S_chunk_alloc(size_t __size, 
                                                            int& __nobjs)
{
    char* __result;
    size_t __total_bytes = __size * __nobjs;
    size_t __bytes_left = _S_end_free - _S_start_free;

    if (__bytes_left >= __total_bytes) {
        __result = _S_start_free;
        _S_start_free += __total_bytes;
        return(__result);
    } else if (__bytes_left >= __size) {
        __nobjs = (int)(__bytes_left/__size);
        __total_bytes = __size * __nobjs;
        __result = _S_start_free;
        _S_start_free += __total_bytes;
        return(__result);
    } else {
        size_t __bytes_to_get = 
	  2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
        // Try to make use of the left-over piece.
        if (__bytes_left > 0) {
	    _Obj* __STL_VOLATILE* __my_free_list =
                        _S_free_list + _S_freelist_index(__bytes_left);
((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list; *__my_free_list = (_Obj*)_S_start_free; } _S_start_free = (char*)malloc(__bytes_to_get); if (0 == _S_start_free) { size_t __i; _Obj* __STL_VOLATILE* __my_free_list; _Obj* __p; // Try to make do with what we have. That can't // hurt. We do not try smaller requests, since that tends // to result in disaster on multi-process machines. for (__i = __size; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN) { __my_free_list = _S_free_list + _S_freelist_index(__i); __p = *__my_free_list; if (0 != __p) { *__my_free_list = __p -> _M_free_list_link; _S_start_free = (char*)__p; _S_end_free = _S_start_free + __i; return(_S_chunk_alloc(__size, __nobjs)); // Any leftover piece will eventually make it to the // right free list. } } _S_end_free = 0; // In case of exception. _S_start_free = (char*)malloc_alloc::allocate(__bytes_to_get); // This should either throw an // exception or remedy the situation. Thus we assume it // succeeded. } _S_heap_size += __bytes_to_get; _S_end_free = _S_start_free + __bytes_to_get; return(_S_chunk_alloc(__size, __nobjs)); }}

这个函数的功能网上很多人都已经有介绍,这里就不重复了,在这只提出我对这段代码一些疑问和思考,如果想错了希望大家能够帮忙指导,这里先谢过了!!

代码的中的一个处理逻辑是:

如果当前内存池中的剩余空间不足一个__size的但是剩余空间大于0时做如下处理(代码中标红的部分):

根据剩余空间的大小将这部分空间编入free_list中。

因为free_list分为块大小为8,16,24,32,...,128,   16个区块,所以要将剩余内存编入,首先需要根据剩余空间大小定位应该放在哪个区块链表上。

代码如下:

		_Obj* __STL_VOLATILE* __my_free_list = _S_free_list + _S_freelist_index(__bytes_left);

_S_freelist_index函数源码:

	static  size_t _S_freelist_index(size_t __bytes) {
        	return (((__bytes) + (size_t)_ALIGN-1)/(size_t)_ALIGN - 1);
  	}
其中_ALIGN是8;这个函数在从free_list中取数据是容易理解的,比如小于8返回的大小为8对应的链表,大于8小于17返回的是大小为16对应的链,以此类推

但是个人认为将剩余空间的数据编入free_list时这个函数定位就有问题了:

比如:剩余空间大小为9,该函数返回的索引的1,对应的是大小为16的区块链表,不是应该放在大小为8的区块链表中更合理吗?

希望大家多多指教


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值