I am playing around with the pmr.
I've got this simple code:
#include <print>
#include <memory_resource>
#include <memory>
#include <vector>
#include <string>
#include <cassert>
#include <unordered_map>
struct LoggingMemoryResource : std::pmr::memory_resource
{
LoggingMemoryResource(std::string name, std::pmr::memory_resource* upstream)
: name(std::move(name)), upstream(upstream)
{
assert(upstream);
}
private:
std::string name;
std::pmr::memory_resource* upstream;
void* do_allocate(std::size_t bytes, std::size_t alignment) override
{
void* ptr = upstream->allocate(bytes, alignment);
std::println("[{} (alloc)] Ptr: {} Size: {} Alignment: {}", name, ptr, bytes, alignment);
return ptr;
}
void do_deallocate(void* ptr, std::size_t bytes, std::size_t alignment) override
{
std::println("[{} (dealloc)] Ptr: {} Size: {} Alignment: {}", name, ptr, bytes, alignment);
upstream->deallocate(ptr, bytes, alignment);
}
bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override
{
return this == &other;
}
};
int main()
{
static constexpr std::size_t SIZE = 1024 * 1024;
std::vector<std::byte> memory{SIZE};
std::pmr::monotonic_buffer_resource mbr{memory.data(), memory.size()};
std::pmr::unsynchronized_pool_resource upr{&mbr};
LoggingMemoryResource pool{"Pool", &upr};
std::pmr::polymorphic_allocator<int> allocator(&pool);
std::unordered_map<int, std::weak_ptr<int>> map;
for(int i = 0; i < 5; ++i) {
auto sharedptr = std::allocate_shared<int>(allocator, i);
std::println("value: {}", *sharedptr.get());
//map[i] = sharedptr;
}
return 0;
}
log result:
[Pool (alloc)] Ptr: 0x7dccefeff220 Size: 32 Alignment: 8
value: 0
[Pool (dealloc)] Ptr: 0x7dccefeff220 Size: 32 Alignment: 8
[Pool (alloc)] Ptr: 0x7dccefeff220 Size: 32 Alignment: 8
value: 1
[Pool (dealloc)] Ptr: 0x7dccefeff220 Size: 32 Alignment: 8
[Pool (alloc)] Ptr: 0x7dccefeff220 Size: 32 Alignment: 8
value: 2
[Pool (dealloc)] Ptr: 0x7dccefeff220 Size: 32 Alignment: 8
[Pool (alloc)] Ptr: 0x7dccefeff220 Size: 32 Alignment: 8
value: 3
[Pool (dealloc)] Ptr: 0x7dccefeff220 Size: 32 Alignment: 8
[Pool (alloc)] Ptr: 0x7dccefeff220 Size: 32 Alignment: 8
value: 4
[Pool (dealloc)] Ptr: 0x7dccefeff220 Size: 32 Alignment: 8
as you can see the address: 0x7dccefeff220
is being reused. Great, this is what I want.
but when I uncomment this part map[i] = sharedptr;
the memory is not being reused anymore:
[Pool (alloc)] Ptr: 0x7667be6fa220 Size: 32 Alignment: 8
value: 0
[Pool (alloc)] Ptr: 0x7667be6fa240 Size: 32 Alignment: 8
value: 1
[Pool (alloc)] Ptr: 0x7667be6fa260 Size: 32 Alignment: 8
value: 2
[Pool (alloc)] Ptr: 0x7667be6fa280 Size: 32 Alignment: 8
value: 3
[Pool (alloc)] Ptr: 0x7667be6fa2a0 Size: 32 Alignment: 8
value: 4
[Pool (dealloc)] Ptr: 0x7667be6fa2a0 Size: 32 Alignment: 8
[Pool (dealloc)] Ptr: 0x7667be6fa280 Size: 32 Alignment: 8
[Pool (dealloc)] Ptr: 0x7667be6fa260 Size: 32 Alignment: 8
[Pool (dealloc)] Ptr: 0x7667be6fa240 Size: 32 Alignment: 8
[Pool (dealloc)] Ptr: 0x7667be6fa220 Size: 32 Alignment: 8
if std::weak_ptr
only modifies the weak ref count (thus it does not hold the strong ref) why is the memory not being reused?
What am I missing here?