ARTICLE AD BOX
There is the following example
// // main.cpp // PlayWithPmr // // Created by Georgios Tsoumplekas on 7/3/26. // #include <iostream> #include <memory_resource> #include <format> void * operator new(size_t size){ std::cout<< "Overloading new operator " << "allocate " << std::dec << size << std::dec <<" bytes" << std::endl; return malloc(size); } void* operator new(std::size_t size, std::align_val_t al) { std::cout << "Aligned new: " << std::dec << size << " bytes, align: " << std::dec << static_cast<size_t>(al) << "\n"; return std::aligned_alloc((std::size_t)al, size); } void operator delete(void * p) noexcept { std::cout<< "Overloading delete operator " << std::endl; free(p); } class debug_resource : public std::pmr::memory_resource { public: explicit debug_resource(std::string name, std::pmr::memory_resource* up = std::pmr::get_default_resource()) : _name{ std::move(name) }, _upstream{ up } { } void* do_allocate(size_t bytes, size_t alignment) override { void* ret = _upstream->allocate(bytes, alignment); std::cout << _name << " do_allocate(): " << std::dec << bytes << " bytes , address " << std::hex << ret << '\n'; return ret; } void do_deallocate(void* ptr, size_t bytes, size_t alignment) override { std::cout << _name << " do_deallocate(): " << std::dec << bytes << " bytes, address " << std::hex << ptr << '\n'; _upstream->deallocate(ptr, bytes, alignment); } bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { return this == &other; } private: std::pmr::string _name{this}; std::pmr::memory_resource* _upstream; }; int main(int argc, const char * argv[]) { // insert code here... alignas(int) char buffer[8094]; std::pmr::monotonic_buffer_resource monotinic_mem(buffer,std::extent_v<decltype(buffer)>,std::pmr::null_memory_resource()); debug_resource debug_pool_mono("mono",&monotinic_mem); std::pmr::unsynchronized_pool_resource pool({32,64},&debug_pool_mono); debug_resource debug_pool("debug_pool",&pool); for(int i =0; i < 100000;++i){ try{ std::cout << "Start iteration::" << std::dec << i << std::endl; std::pmr::vector<int> vec(64,&debug_pool); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.emplace_back(); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); vec.erase(vec.begin()); std::cout << "End iteration" << std::endl; } catch(const std::bad_alloc& e){ std::cout << "Allocation failed: " << e.what() << '\n'; exit(-1); } } }In this implementation I try to use monotonic buffer for allocate memory for a vector and in combination with pool avoid unnecessary new deletes. My expectation is that in every loop the vec retrieves the memory from the pool , in the end of the loop return this memory in the pool , and next vector can utilize this memory .Following up this approach the monotonic buffer shoukd not grow infinitely, but a recycle approach of this happens. But investigation the implementation this does not happen. After some iteration the buffer is exhausted and try to allocate memory from upstream which is null_memory_resource to create an exception.
Probably I am missing a key point how pools work. If the largest_required_pool_block is small more iteration take place before exception. If is large less. Also this does not make any sense to me since this control how often goes to upstream .If it is larger rarely goes to upstream which the monotonic buffer
Below is the links of the different approaches
https://godbolt.org/z/MvKEnY593
https://godbolt.org/z/1qGarvs3s
How the largest_required_pool_block affects the allocated size per request? I see that if this 1K the bytes that are tried to be allocated are about 3848 which does not do any sense to me. My expectation that the allocated size will be 64 *4 (size of int) + overhead for pmr vectors
Why the program runs out the monotonic buffer?
