0 Tage Serie
cpp / expert
Snippet

Implementierung einer eigenen polymorphen Speicherressource (std::pmr)

Polymorphe Speicherressourcen (std::pmr), eingeführt in C++17, ermöglichen die Laufzeitanpassung von Allokationsstrategien, ohne die Templates der Container zu verändern. Durch Überschreiben von do_allocate, do_deallocate und do_is_equal von std::pmr::memory_resource können Entwickler eigene Tracking-, Arena- oder Pool-Allokatoren mittels objektorientierter Vererbung umsetzen.

snippet.cpp
cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <memory_resource>
#include <vector>
class TrackingMemoryResource : public std::pmr::memory_resource {
private:
std::pmr::memory_resource* upstream_;
size_t total_allocated_{0};
protected:
void* do_allocate(size_t bytes, size_t alignment) override {
total_allocated_ += bytes;
std::cout << "[PMR Alloc] " << bytes << " bytes (Total: " << total_allocated_ << ")\n";
return upstream_->allocate(bytes, alignment);
}
void do_deallocate(void* p, size_t bytes, size_t alignment) override {
std::cout << "[PMR Dealloc] Freeing " << bytes << " bytes\n";
upstream_->deallocate(p, bytes, alignment);
}
bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
return this == &other;
}
public:
explicit TrackingMemoryResource(std::pmr::memory_resource* upstream = std::pmr::get_default_resource())
: upstream_(upstream) {}
};
int main() {
TrackingMemoryResource tracker;
std::pmr::vector<int> numbers(&tracker);
numbers.reserve(4);
numbers.push_back(42);
}
Erklärung
1
class TrackingMemoryResource : public std::pmr::memory_resource
Erbt von der standardmäßigen polymorphen Basisklassen-Schnittstelle für Speicherallokation.
2
void* do_allocate(size_t bytes, size_t alignment) override
Geschützter virtueller Hook für benutzerdefiniertes Tracking vor Weiterleitung an Upstream.
3
std::pmr::vector<int> numbers(&tracker);
Verwendet Laufzeit-Allokator-Referenz statt Compile-Time-Template-Parameter.