Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/memory/set default resource"

From cppreference.com
< cpp‎ | memory
m (Example: rm "copy-pasta" comment (it's applicable only to the 2nd scope.)
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 {{tt|r}} is not null, sets the default memory resource pointer to {{tt|r}}; otherwise, sets the default memory resource pointer to {{c|std::pmr::new_delete_resource()}}.
+
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{ {1, 2, 3, 4} };
+
         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
+
|p=true
| output=
+
|output=
 
Entering scope #1 (without buffer on stack)...
 
Entering scope #1 (without buffer on stack)...
 
Creating vector v...
 
Creating vector v...
+ Allocating 8 bytes @ 0x1d27030
+
+ Allocating 8 bytes @ 0x1f75c30
v.data() @ 0x1d27030
+
v.data() @ 0x1f75c30
 
Requesting more...
 
Requesting more...
+ Allocating 16 bytes @ 0x1d27050
+
+ Allocating 16 bytes @ 0x1f75c50
- Deallocating 8 bytes @ 0x1d27030
+
- Deallocating 8 bytes @ 0x1f75c30
+ Allocating 32 bytes @ 0x1d27070
+
v.size(): 5
- Deallocating 16 bytes @ 0x1d27050
+
v.size(): 6
+ Allocating 64 bytes @ 0x1d270a0
+
v.size(): 7
- Deallocating 32 bytes @ 0x1d27070
+
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 @ 0x1d270a0
+
- Deallocating 64 bytes @ 0x1f75ca0
  
 
Entering scope #2 (with buffer on stack)...
 
Entering scope #2 (with buffer on stack)...
Allocating buffer on stack: 16 bytes @ 0x7ffd248ae2f0
+
Allocating buffer on stack: 16 bytes @ 0x7fffbe9f8240
 
Creating vector v...
 
Creating vector v...
v.data() @ 0x7ffd248ae2f0
+
v.data() @ 0x7fffbe9f8240
 
Requesting more...
 
Requesting more...
+ Allocating 64 bytes @ 0x1d270a0
+
+ Allocating 64 bytes @ 0x1f75ca0
+ Allocating 128 bytes @ 0x1d270f0
+
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 @ 0x1d270f0
+
- Deallocating 128 bytes @ 0x1f75cf0
- Deallocating 64 bytes @ 0x1d270a0
+
- 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

 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
 
Dynamic memory management
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Allocators
Garbage collection support
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)



 
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

#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

gets the default std::pmr::memory_resource
(function) [edit]
returns a static program-wide std::pmr::memory_resource that uses the global operator new and operator delete to allocate and deallocate memory
(function) [edit]