foonathan / memory

STL compatible C++ memory allocator library using a new RawAllocator concept that is similar to an Allocator but easier to use and write.

Home Page:https://memory.foonathan.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

memory_pool_collection fails to allocate memory

cohdan opened this issue · comments

Hi,
I have the following code:

using memory_pool = foonathan::memory::memory_pool_collection<memory::node_pool,
                                             memory::identity_buckets,
                                             memory::fixed_block_allocator<memory::default_allocator>>;

class something {
public:
    void init();
private:
   unique_ptr<memory_pool>     _object_pool;
}

void something::init() {
   size_to_allocate = 1024*1024;
   

    initializer_list<size_t> node_sizes = {memory::list_node_size<pair<init, int>>::value,
                                           memory::unordered_map_node_size<int, list<pair<int,int>>::iterator>::value,
                                           sizeof(memory::unordered_map<int, list<pair<int,int>>::iterator>::iterator)};
    auto max_node_size = std::max(node_sizes);

    _object_pool = make_unique<memory_pool>(max_node_size, size_to_allocate);
    _object_pool->allocate_node(32);
}

When executing this code an exception is thrown:

[foonathan::memory] Allocator foonathan::memory::fixed_block_allocator (at 0x600001ed4158) ran out of memory trying to allocate 0 bytes.

Tried also to replace the _object_pool->allocate_node(32); with _object_pool->get_allocator().allocate_block(); and got the same exception.

This is a simplification of the code that I want to achieve at the end which is using this pool collection for a couple of containers (one list and one map as can be seen). My understanding is that the pool collection will allocate the block in the first call for allocate_node/allocate_array - but seems like this is not the case. How am I supposed to trigger the actual memory allocation? Or am I completely off?

Thanks.

It seems like the fixed block allocator does not work with memory pool collection - when I changed it to the growing block allocator all seems to work fine. I'd think that there shouldn't be a reason for the fixed allocator not to work in this case, am I wrong?
Anyway, I continue to look into this because I do need a fixed allocator and I do need several node sizes. Will be happy if anyone can still help.
Thanks.

so the issue is that the memory pool collection always looks at the next block size when assigning memory to a bucket (free list) which will not work with fixed buffer as fixed buffer allocates the block in the creation of the object and then next block will always be 0.

@foonathan is this an intended behavior or a bug?
Thanks.

In the meantime I wrote a wrppar class to the fixed allocator that returns the allocated block_size in next_block_size (instead of zero) and it seems to work fine.

template<class RawAllocator = memory::default_allocator>
    class fixed_block_allocator_for_memory_pool_collection {

    public:
        using allocator_type = memory::traits_detail::allocator_type<RawAllocator>;
        explicit fixed_block_allocator_for_memory_pool_collection(std::size_t block_size) noexcept
                                                                  : _underline_allocator(block_size, allocator_type()), _block_size(block_size) {}

        memory::memory_block allocate_block() {
            return _underline_allocator.allocate_block();
        }

        void deallocate_block(memory::memory_block block) noexcept {
            _underline_allocator.deallocate_block(block);
        }
        
        allocator_type& get_allocator() noexcept
        {
            return _underline_allocator.get_allocator();
        }

        std::size_t next_block_size() const noexcept {
            return _block_size;
        }

    private:
        size_t                                          _block_size;
        memory::fixed_block_allocator<RawAllocator>     _underline_allocator;
    };

Please let me know if this is something that you would like me to upload as a PR.

I've changed memory_pool_collection to use the current block size instead, which should also solve the problem.