STL中的空间配置器(3)

char *default_alloc::chunk_alloc(size_t size, int &nobjs)
{
    char *result = 0;
    size_t total_bytes = size*nobjs;
    size_t bytes_left = end_free - start_free;    //内存池剩余空间
    if (bytes_left >= total_bytes)
    {//内存池足够提供所需内存
        result = start_free;
        start_free += total_bytes;
        return result;
    }
    else if (bytes_left >= size)
    {//内存池足够供应一个以上的区块
        nobjs = bytes_left / size;
        total_bytes = nobjs * size;
        result = start_free;
        start_free += total_bytes;
        return result;
    }
    else
    {//内存池一块区块也供应不了
        size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);;
        if (bytes_left>0)
        {//将内存池的零头分配给合适的freelist
            obj **my_free_list = free_list + FREELIST_INDEX(bytes_left);
            ((obj *)start_free)->next = *my_free_list;
            *my_free_list = (obj *)start_free;
        }
        start_free = (char *)malloc(bytes_to_get);
        if (!start_free)
        {//系统堆内存不足,寻找还未使用的freelist
            obj *p = 0;
            obj **my_free_list = 0;
            for (int i = size; i < MAX_BYTES; ++i)
            {
                my_free_list = free_list + FREELIST_INDEX(i);
                p = *my_free_list;
                if (0 != p)
                {//还有未使用的freelist
                    start_free = (char *)p;
                    *my_free_list = p->next;
                    end_free = start_free + i;
                    //递归调用,修正nobjs
                    return chunk_alloc(size, nobjs);
                }
            }
            //没内存可用,寄希望于第一级的new-handler或抛出异常
            end_free = 0;
            start_free = (char *)malloc_alloc::allocate(bytes_to_get);
        }
        heap_size += bytes_to_get;
        end_free = start_free + bytes_to_get;
        return chunk_alloc(size, nobjs);//递归调用,修正nobjs
    }
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/102b355f40f3daf6aefb7bdbde8845d7.html