Difference between revisions of "cpp/memory/set default resource"
From cppreference.com
m (→Example: rm "copy-pasta" comment (it's applicable only to the 2nd scope.) |
Andreas Krug (Talk | contribs) m (fmt) |
||
(4 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
{{cpp/memory/pmr/title|set_default_resource}} | {{cpp/memory/pmr/title|set_default_resource}} | ||
{{cpp/memory/navbar}} | {{cpp/memory/navbar}} | ||
− | {{ddcl|header=memory_resource | since=c++17| | + | {{ddcl|header=memory_resource|since=c++17| |
− | std::pmr::memory_resource* set_default_resource(std::pmr::memory_resource* r) noexcept; | + | std::pmr::memory_resource* set_default_resource( std::pmr::memory_resource* r ) noexcept; |
}} | }} | ||
− | If {{ | + | If {{c|r}} is not null, sets the default memory resource pointer to {{c|r}}; otherwise, sets the default memory resource pointer to {{c|std::pmr::new_delete_resource()}}. |
The ''default memory resource pointer'' is used by certain facilities when an explicit memory resource is not supplied. The initial default memory resource pointer is the return value of {{lc|std::pmr::new_delete_resource}}. | The ''default memory resource pointer'' is used by certain facilities when an explicit memory resource is not supplied. The initial default memory resource pointer is the return value of {{lc|std::pmr::new_delete_resource}}. | ||
Line 11: | Line 11: | ||
This function is thread-safe. Every call to {{tt|std::pmr::set_default_resource}} ''synchronizes with'' (see {{lc|std::memory_order}}) the subsequent {{tt|std::pmr::set_default_resource}} and {{lc|std::pmr::get_default_resource}} calls. | This function is thread-safe. Every call to {{tt|std::pmr::set_default_resource}} ''synchronizes with'' (see {{lc|std::memory_order}}) the subsequent {{tt|std::pmr::set_default_resource}} and {{lc|std::pmr::get_default_resource}} calls. | ||
− | === Return value === | + | ===Return value=== |
− | + | ||
Returns the previous value of the default memory resource pointer. | Returns the previous value of the default memory resource pointer. | ||
− | === Example === | + | ===Example=== |
{{example | {{example | ||
|code= | |code= | ||
Line 22: | Line 21: | ||
#include <cstdint> | #include <cstdint> | ||
#include <iostream> | #include <iostream> | ||
+ | #include <iterator> | ||
#include <memory_resource> | #include <memory_resource> | ||
#include <vector> | #include <vector> | ||
− | class noisy_allocator : public std::pmr::memory_resource { | + | class noisy_allocator : public std::pmr::memory_resource |
− | void* do_allocate(std::size_t bytes, std::size_t alignment) override { | + | { |
+ | void* do_allocate(std::size_t bytes, std::size_t alignment) override | ||
+ | { | ||
std::cout << "+ Allocating " << bytes << " bytes @ "; | std::cout << "+ Allocating " << bytes << " bytes @ "; | ||
void* p = std::pmr::new_delete_resource()->allocate(bytes, alignment); | void* p = std::pmr::new_delete_resource()->allocate(bytes, alignment); | ||
Line 33: | Line 35: | ||
} | } | ||
− | void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override { | + | void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override |
+ | { | ||
std::cout << "- Deallocating " << bytes << " bytes @ " << p << '\n'; | std::cout << "- Deallocating " << bytes << " bytes @ " << p << '\n'; | ||
return std::pmr::new_delete_resource()->deallocate(p, bytes, alignment); | return std::pmr::new_delete_resource()->deallocate(p, bytes, alignment); | ||
} | } | ||
− | bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { | + | bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override |
+ | { | ||
return std::pmr::new_delete_resource()->is_equal(other); | return std::pmr::new_delete_resource()->is_equal(other); | ||
} | } | ||
}; | }; | ||
− | int main() { | + | int main() |
+ | { | ||
constexpr int push_back_limit{16}; | constexpr int push_back_limit{16}; | ||
noisy_allocator mem; | noisy_allocator mem; | ||
Line 51: | Line 56: | ||
std::cout << "Entering scope #1 (without buffer on stack)...\n"; | std::cout << "Entering scope #1 (without buffer on stack)...\n"; | ||
std::cout << "Creating vector v...\n"; | std::cout << "Creating vector v...\n"; | ||
− | std::pmr::vector<std::uint16_t> v | + | std::pmr::vector<std::uint16_t> v{1, 2, 3, 4}; |
std::cout << "v.data() @ " << v.data() << '\n'; | std::cout << "v.data() @ " << v.data() << '\n'; | ||
std::cout << "Requesting more...\n"; | std::cout << "Requesting more...\n"; | ||
− | for (int i{0}; i != push_back_limit; ++i) { | + | for (int i{0}; i != push_back_limit; ++i) |
+ | { | ||
v.push_back(i); | v.push_back(i); | ||
+ | std::cout << "v.size(): " << v.size() << '\n'; | ||
} | } | ||
std::cout << "Exiting scope #1...\n"; | std::cout << "Exiting scope #1...\n"; | ||
Line 72: | Line 79: | ||
std::cout << "Creating vector v...\n"; | std::cout << "Creating vector v...\n"; | ||
− | std::pmr::vector<std::uint16_t> v{ {1, 2, 3, 4}, &mem_res }; | + | std::pmr::vector<std::uint16_t> v{<!---->{1, 2, 3, 4}, &mem_res<!---->}; |
std::cout << "v.data() @ " << v.data() << '\n'; // equals to `buffer` address | std::cout << "v.data() @ " << v.data() << '\n'; // equals to `buffer` address | ||
std::cout << "Requesting more...\n"; | std::cout << "Requesting more...\n"; | ||
− | for (int i{0}; i != push_back_limit; ++i) { | + | for (int i{0}; i != push_back_limit; ++i) |
+ | { | ||
v.push_back(i); | v.push_back(i); | ||
+ | std::cout << "v.size(): " << v.size() << '\n'; | ||
} | } | ||
std::cout << "Exiting scope #2...\n"; | std::cout << "Exiting scope #2...\n"; | ||
} | } | ||
} | } | ||
− | + | |p=true | |
− | + | |output= | |
Entering scope #1 (without buffer on stack)... | Entering scope #1 (without buffer on stack)... | ||
Creating vector v... | Creating vector v... | ||
− | + Allocating 8 bytes @ | + | + Allocating 8 bytes @ 0x1f75c30 |
− | v.data() @ | + | v.data() @ 0x1f75c30 |
Requesting more... | Requesting more... | ||
− | + Allocating 16 bytes @ | + | + Allocating 16 bytes @ 0x1f75c50 |
− | - Deallocating 8 bytes @ | + | - Deallocating 8 bytes @ 0x1f75c30 |
− | + Allocating 32 bytes @ | + | v.size(): 5 |
− | - Deallocating 16 bytes @ | + | v.size(): 6 |
− | + Allocating 64 bytes @ | + | v.size(): 7 |
− | - Deallocating 32 bytes @ | + | v.size(): 8 |
+ | + Allocating 32 bytes @ 0x1f75c70 | ||
+ | - Deallocating 16 bytes @ 0x1f75c50 | ||
+ | v.size(): 9 | ||
+ | v.size(): 10 | ||
+ | v.size(): 11 | ||
+ | v.size(): 12 | ||
+ | v.size(): 13 | ||
+ | v.size(): 14 | ||
+ | v.size(): 15 | ||
+ | v.size(): 16 | ||
+ | + Allocating 64 bytes @ 0x1f75ca0 | ||
+ | - Deallocating 32 bytes @ 0x1f75c70 | ||
+ | v.size(): 17 | ||
+ | v.size(): 18 | ||
+ | v.size(): 19 | ||
+ | v.size(): 20 | ||
Exiting scope #1... | Exiting scope #1... | ||
− | - Deallocating 64 bytes @ | + | - Deallocating 64 bytes @ 0x1f75ca0 |
Entering scope #2 (with buffer on stack)... | Entering scope #2 (with buffer on stack)... | ||
− | Allocating buffer on stack: 16 bytes @ | + | Allocating buffer on stack: 16 bytes @ 0x7fffbe9f8240 |
Creating vector v... | Creating vector v... | ||
− | v.data() @ | + | v.data() @ 0x7fffbe9f8240 |
Requesting more... | Requesting more... | ||
− | + Allocating 64 bytes @ | + | + Allocating 64 bytes @ 0x1f75ca0 |
− | + Allocating 128 bytes @ | + | v.size(): 5 |
+ | v.size(): 6 | ||
+ | v.size(): 7 | ||
+ | v.size(): 8 | ||
+ | v.size(): 9 | ||
+ | v.size(): 10 | ||
+ | v.size(): 11 | ||
+ | v.size(): 12 | ||
+ | v.size(): 13 | ||
+ | v.size(): 14 | ||
+ | v.size(): 15 | ||
+ | v.size(): 16 | ||
+ | + Allocating 128 bytes @ 0x1f75cf0 | ||
+ | v.size(): 17 | ||
+ | v.size(): 18 | ||
+ | v.size(): 19 | ||
+ | v.size(): 20 | ||
Exiting scope #2... | Exiting scope #2... | ||
− | - Deallocating 128 bytes @ | + | - Deallocating 128 bytes @ 0x1f75cf0 |
− | - Deallocating 64 bytes @ | + | - Deallocating 64 bytes @ 0x1f75ca0 |
}} | }} | ||
− | === See also === | + | ===See also=== |
{{dsc begin}} | {{dsc begin}} | ||
{{dsc inc|cpp/memory/dsc get_default_resource}} | {{dsc inc|cpp/memory/dsc get_default_resource}} | ||
Line 116: | Line 157: | ||
{{dsc end}} | {{dsc end}} | ||
− | {{langlinks|es|ja|ru|zh}} | + | {{langlinks|de|es|ja|ru|zh}} |
Latest revision as of 10:19, 10 October 2023
Defined in header <memory_resource>
|
||
std::pmr::memory_resource* set_default_resource( std::pmr::memory_resource* r ) noexcept; |
(since C++17) | |
If r is not null, sets the default memory resource pointer to r; otherwise, sets the default memory resource pointer to std::pmr::new_delete_resource().
The default memory resource pointer is used by certain facilities when an explicit memory resource is not supplied. The initial default memory resource pointer is the return value of std::pmr::new_delete_resource.
This function is thread-safe. Every call to std::pmr::set_default_resource
synchronizes with (see std::memory_order) the subsequent std::pmr::set_default_resource
and std::pmr::get_default_resource calls.
[edit] Return value
Returns the previous value of the default memory resource pointer.
[edit] Example
Run this code
#include <array> #include <cstddef> #include <cstdint> #include <iostream> #include <iterator> #include <memory_resource> #include <vector> class noisy_allocator : public std::pmr::memory_resource { void* do_allocate(std::size_t bytes, std::size_t alignment) override { std::cout << "+ Allocating " << bytes << " bytes @ "; void* p = std::pmr::new_delete_resource()->allocate(bytes, alignment); std::cout << p << '\n'; return p; } void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override { std::cout << "- Deallocating " << bytes << " bytes @ " << p << '\n'; return std::pmr::new_delete_resource()->deallocate(p, bytes, alignment); } bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { return std::pmr::new_delete_resource()->is_equal(other); } }; int main() { constexpr int push_back_limit{16}; noisy_allocator mem; std::pmr::set_default_resource(&mem); { std::cout << "Entering scope #1 (without buffer on stack)...\n"; std::cout << "Creating vector v...\n"; std::pmr::vector<std::uint16_t> v{1, 2, 3, 4}; std::cout << "v.data() @ " << v.data() << '\n'; std::cout << "Requesting more...\n"; for (int i{0}; i != push_back_limit; ++i) { v.push_back(i); std::cout << "v.size(): " << v.size() << '\n'; } std::cout << "Exiting scope #1...\n"; } std::cout << '\n'; { std::cout << "Entering scope #2 (with buffer on stack)...\n"; std::uint8_t buffer[16]; std::cout << "Allocating buffer on stack: " << sizeof buffer << " bytes @ " << static_cast<void*>(buffer) << '\n'; std::pmr::monotonic_buffer_resource mem_res{std::data(buffer), std::size(buffer)}; std::cout << "Creating vector v...\n"; std::pmr::vector<std::uint16_t> v{{1, 2, 3, 4}, &mem_res}; std::cout << "v.data() @ " << v.data() << '\n'; // equals to `buffer` address std::cout << "Requesting more...\n"; for (int i{0}; i != push_back_limit; ++i) { v.push_back(i); std::cout << "v.size(): " << v.size() << '\n'; } std::cout << "Exiting scope #2...\n"; } }
Possible output:
Entering scope #1 (without buffer on stack)... Creating vector v... + Allocating 8 bytes @ 0x1f75c30 v.data() @ 0x1f75c30 Requesting more... + Allocating 16 bytes @ 0x1f75c50 - Deallocating 8 bytes @ 0x1f75c30 v.size(): 5 v.size(): 6 v.size(): 7 v.size(): 8 + Allocating 32 bytes @ 0x1f75c70 - Deallocating 16 bytes @ 0x1f75c50 v.size(): 9 v.size(): 10 v.size(): 11 v.size(): 12 v.size(): 13 v.size(): 14 v.size(): 15 v.size(): 16 + Allocating 64 bytes @ 0x1f75ca0 - Deallocating 32 bytes @ 0x1f75c70 v.size(): 17 v.size(): 18 v.size(): 19 v.size(): 20 Exiting scope #1... - Deallocating 64 bytes @ 0x1f75ca0 Entering scope #2 (with buffer on stack)... Allocating buffer on stack: 16 bytes @ 0x7fffbe9f8240 Creating vector v... v.data() @ 0x7fffbe9f8240 Requesting more... + Allocating 64 bytes @ 0x1f75ca0 v.size(): 5 v.size(): 6 v.size(): 7 v.size(): 8 v.size(): 9 v.size(): 10 v.size(): 11 v.size(): 12 v.size(): 13 v.size(): 14 v.size(): 15 v.size(): 16 + Allocating 128 bytes @ 0x1f75cf0 v.size(): 17 v.size(): 18 v.size(): 19 v.size(): 20 Exiting scope #2... - Deallocating 128 bytes @ 0x1f75cf0 - Deallocating 64 bytes @ 0x1f75ca0
[edit] See also
(C++17) |
gets the default std::pmr::memory_resource (function) |
(C++17) |
returns a static program-wide std::pmr::memory_resource that uses the global operator new and operator delete to allocate and deallocate memory (function) |