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.