{"id":8311,"date":"2023-10-02T08:35:05","date_gmt":"2023-10-02T08:35:05","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=8311"},"modified":"2023-10-02T08:35:05","modified_gmt":"2023-10-02T08:35:05","slug":"special-allocators-with-c17","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/special-allocators-with-c17\/","title":{"rendered":"Special Allocators with C++17"},"content":{"rendered":"\n<p>I introduced in my last post &#8220;Polymorphic Allocators with C++17&#8221; the theory of polymorphic allocators in C++17. Today, I will apply the theory.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/chips-20072_1280-1030x686.jpg\" alt=\"\" class=\"wp-image-8430\" style=\"width:650px\" width=\"650\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/chips-20072_1280-1030x686.jpg 1030w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/chips-20072_1280-300x200.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/chips-20072_1280-768x512.jpg 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/chips-20072_1280-705x470.jpg 705w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/chips-20072_1280.jpg 1280w\" sizes=\"(max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n\n\n\n<p>Before I go on, here are the essential parts of my last post: &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/polymorphic-allocators-in-c17\/\" data-type=\"link\" data-id=\"https:\/\/www.modernescpp.com\/index.php\/polymorphic-allocators-in-c17\/\">Polymorphic Allocators with C++17<\/a>&#8220;. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Short Reminder<\/h2>\n\n\n\n<p>The following program uses polymorphic allocators. <\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto; gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ polymorphicAllocator.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;array&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;cstddef&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;memory_resource&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;vector&gt;<\/span>\n\n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>() {\n\n    std<span style=\"color: #555555\">::<\/span>array<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>byte, <span style=\"color: #FF6600\">200<\/span><span style=\"color: #555555\">&gt;<\/span> buf1;                               <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n    std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>monotonic_buffer_resource pool1{buf1.data(), buf1.size()};\n    std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> myVec1{<span style=\"color: #555555\">&amp;<\/span>pool1};                          <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #007788; font-weight: bold\">int<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">&lt;<\/span> <span style=\"color: #FF6600\">5<\/span>; <span style=\"color: #555555\">++<\/span>i) {\n        myVec1.push_back(i);\n    }\n\n    <span style=\"color: #007788; font-weight: bold\">char<\/span> buf2[<span style=\"color: #FF6600\">200<\/span>] <span style=\"color: #555555\">=<\/span> {};                                           <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n    std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>monotonic_buffer_resource pool2{std<span style=\"color: #555555\">::<\/span>data(buf2), std<span style=\"color: #555555\">::<\/span>size(buf2)};\n    std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> myVec2{<span style=\"color: #555555\">&amp;<\/span>pool2};\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #007788; font-weight: bold\">int<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">&lt;<\/span> <span style=\"color: #FF6600\">200<\/span>; <span style=\"color: #555555\">++<\/span>i) {\n        myVec2.push_back(i);\n    }\n\n}\n<\/pre><\/div>\n\n\n\n<p>Now, I want to focus on my<code>Vec2<\/code>. It pushes 200 <code>int<\/code>s onto the <code>std::pmr::vector&lt;int&gt;<\/code>. 200<code> int<\/code>s do not fit into a <code>char buf[200]<\/code> and, therefore,<code> std::pmr::new_delete_resource()<\/code> as the so-called upstream allocator kicks in and calls the global <code>new <\/code>for the remaining elements. Let me instrumentalize the upstream allocator.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Tracking Allocator<\/h2>\n\n\n\n<p>The following program is based on the previous one, uses a tracking allocator, and makes the dynamic memory allocation and deallocation visible.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto; gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ trackAllocator.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;array&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;cstdlib&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;format&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;memory_resource&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;vector&gt;<\/span>\n\n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">TrackAllocator<\/span> <span style=\"color: #555555\">:<\/span> <span style=\"color: #006699; font-weight: bold\">public<\/span> std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>memory_resource {\n    <span style=\"color: #007788; font-weight: bold\">void<\/span><span style=\"color: #555555\">*<\/span> do_allocate(std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> bytes, std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> alignment) override {\n        <span style=\"color: #007788; font-weight: bold\">void<\/span><span style=\"color: #555555\">*<\/span> p <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>new_delete_resource()<span style=\"color: #555555\">-&gt;<\/span>allocate(bytes, alignment);\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> std<span style=\"color: #555555\">::<\/span>format(<span style=\"color: #CC3300\">&quot;  do_allocate: {:6} bytes at {}<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>, bytes, p);\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> p;\n    }\n \n    <span style=\"color: #007788; font-weight: bold\">void<\/span> do_deallocate(<span style=\"color: #007788; font-weight: bold\">void<\/span><span style=\"color: #555555\">*<\/span> p, std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> bytes, std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> alignment) override {\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> std<span style=\"color: #555555\">::<\/span>format(<span style=\"color: #CC3300\">&quot;  do_deallocate: {:4} bytes at {}<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>, bytes, p);\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>new_delete_resource()<span style=\"color: #555555\">-&gt;<\/span>deallocate(p, bytes, alignment);\n    }\n \n    <span style=\"color: #007788; font-weight: bold\">bool<\/span> do_is_equal(<span style=\"color: #006699; font-weight: bold\">const<\/span> std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>memory_resource<span style=\"color: #555555\">&amp;<\/span> other) <span style=\"color: #006699; font-weight: bold\">const<\/span> noexcept override {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>new_delete_resource()<span style=\"color: #555555\">-&gt;<\/span>is_equal(other);\n    }\n};\n\n\n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>() {\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n    TrackAllocator trackAllocator;                         <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n    std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>set_default_resource(<span style=\"color: #555555\">&amp;<\/span>trackAllocator);       <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;myVec1<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>;\n\n    std<span style=\"color: #555555\">::<\/span>array<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>byte, <span style=\"color: #FF6600\">200<\/span><span style=\"color: #555555\">&gt;<\/span> buf1;\n    std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>monotonic_buffer_resource pool1{buf1.data(), buf1.size()};\n    std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> myVec1{<span style=\"color: #555555\">&amp;<\/span>pool1};                  <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #007788; font-weight: bold\">int<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">&lt;<\/span> <span style=\"color: #FF6600\">5<\/span>; <span style=\"color: #555555\">++<\/span>i) {\n        myVec1.push_back(i);\n    }\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;myVec2<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>;\n\n    <span style=\"color: #007788; font-weight: bold\">char<\/span> buf2[<span style=\"color: #FF6600\">200<\/span>] <span style=\"color: #555555\">=<\/span> {}; \n    std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>monotonic_buffer_resource pool2{std<span style=\"color: #555555\">::<\/span>data(buf2), std<span style=\"color: #555555\">::<\/span>size(buf2)};\n    std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> myVec2{<span style=\"color: #555555\">&amp;<\/span>pool2};                  <span style=\"color: #0099FF; font-style: italic\">\/\/ (4)<\/span>\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #007788; font-weight: bold\">int<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">&lt;<\/span> <span style=\"color: #FF6600\">200<\/span>; <span style=\"color: #555555\">++<\/span>i) {\n        myVec2.push_back(i);\n    }\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n}\n<\/pre><\/div>\n\n\n\n<p><code>TrackAllocator<\/code> is a tracking allocator. It derives from the interface class <code>std::pmr::memory_resource<\/code>, from which all memory resources derive. <code>TrackAllocator <\/code>defines the three required member functions <code>do_allocate<\/code>, <code>do_deallocate<\/code>, and <code>do_is_equal<\/code>.  Each call forwards its call to <code>std::pmr::new_delete_resource<\/code>. <code>std:pmr::new_delete_resource<\/code> is the default memory resource and calls the global <code>new <\/code>and <code>delete<\/code>. The member function&#8217;s job<code> do_is_equal<\/code> is to<code> <\/code>check that the two memory resources are equal. The interesting point in the program is the visualization of the allocation and the deallocation in the member functions <code>do_allocate <\/code>and <code>do_deallocate<\/code>.<\/p>\n\n\n\n<p>By instantiating the<code> TrackAllocator<\/code> (line 1) and make it as the default resource (line 2). <code>myVec1<\/code> (line 3) and <code>myVec2<\/code> (line 4) use them as the upstream allocator. This allocator kicks in if the primary allocator is consumed. This fallback is not necessary for <code>myVec1<\/code>, but necessary for<code> myVec2<\/code>. <\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/09\/trackAllocator-1030x750.png\" alt=\"\" class=\"wp-image-8327\" style=\"width:500px\" width=\"500\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/09\/trackAllocator-1030x750.png 1030w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/09\/trackAllocator-300x218.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/09\/trackAllocator-768x559.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/09\/trackAllocator-705x513.png 705w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/09\/trackAllocator.png 1115w\" sizes=\"(max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n\n\n\n<p>This output shows the dynamical allocation and deallocation of <code>myVec2 <\/code>until all <code>int<\/code>s fit into the <code>std::pmr::vector&lt;int&gt;<\/code>.<\/p>\n\n\n\n<p>You can also bind an upstream allocator to a specific container.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Non-Allocating Allocator<\/h2>\n\n\n\n<p><code>std::pmr::null_resource_allocator<\/code> is a special allocator. Using this memory resource for allocating causes a <code>std::bad_alloc<\/code> exception. This memory resource ensures that you do not arbitrarily allocate memory on the heap. Let&#8217;s try it out.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto; gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ nullMemoryResource.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;array&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;cstddef&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt; <\/span>\n<span style=\"color: #009999\">#include &lt;memory_resource&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;string&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;vector&gt;<\/span>\n\n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>() {\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n \n    std<span style=\"color: #555555\">::<\/span>array<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>byte, <span style=\"color: #FF6600\">2000<\/span><span style=\"color: #555555\">&gt;<\/span> buf;\n    std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>monotonic_buffer_resource pool{buf.data(), buf.size(),  <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n                                           std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>null_memory_resource()};\n    std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>pmr<span style=\"color: #555555\">::<\/span>string<span style=\"color: #555555\">&gt;<\/span> myVec{<span style=\"color: #555555\">&amp;<\/span>pool};                  <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n    try {\n        <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #007788; font-weight: bold\">int<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">&lt;<\/span> <span style=\"color: #FF6600\">100<\/span>; <span style=\"color: #555555\">++<\/span>i) {                               <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n            std<span style=\"color: #555555\">::<\/span>cerr <span style=\"color: #555555\">&lt;&lt;<\/span> i <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot; &quot;<\/span>;\n            myVec.emplace_back(<span style=\"color: #CC3300\">&quot;A short string&quot;<\/span>);\n        }\n    }\n    <span style=\"color: #006699; font-weight: bold\">catch<\/span> (<span style=\"color: #006699; font-weight: bold\">const<\/span> std<span style=\"color: #555555\">::<\/span>bad_alloc<span style=\"color: #555555\">&amp;<\/span> e) {                                 <span style=\"color: #0099FF; font-style: italic\">\/\/ (4)<\/span>\n        std<span style=\"color: #555555\">::<\/span>cerr <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> e.what() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n    }\n    \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n    \n}\n<\/pre><\/div>\n\n\n\n<p>First, I allocate memory on the stack and initialize <code>std::pmr::monotonic_buffer_resource<\/code> with it. Then, I use this memory resource and <code>std::pmr::null_memory_resource<\/code> as an upstream allocator (line 1).  In line 2, I create a <code>std::pmr::vector&lt;std::pmr::string&gt;<\/code>. Because I use a<code> std::pmr::string, <\/code>the string also uses the memory resource and its upstream allocator. When I use <code>std::pmr::vector&lt;std::string&gt;<\/code>, <code>std::string<\/code> allocates using the global <code>new <\/code>and <code>delete<\/code>. Finally, in line (3), I create 100 strings and catch in line (4) a <code>std::bad_alloc <\/code>exception. I got what I deserved. 100 strings will not fit into a <code>std::array&lt;std::byte, 2000&gt;<\/code> buffer. After 17 strings, the buffer is consumed.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"564\" height=\"244\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/09\/nullMemoryResource.png\" alt=\"\" class=\"wp-image-8331\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/09\/nullMemoryResource.png 564w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/09\/nullMemoryResource-300x130.png 300w\" sizes=\"auto, (max-width: 564px) 100vw, 564px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next?<\/h2>\n\n\n\n<p>You may have heard it already. The<code> std::pmr::monotonic_buffer <\/code>has outstanding features. It is pretty fast and does not free memory.  I will provide the number in my next post.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I introduced in my last post &#8220;Polymorphic Allocators with C++17&#8221; the theory of polymorphic allocators in C++17. Today, I will apply the theory. Before I go on, here are the essential parts of my last post: &#8220;Polymorphic Allocators with C++17&#8220;. A Short Reminder The following program uses polymorphic allocators. \/\/ polymorphicAllocator.cpp #include &lt;array&gt; #include &lt;cstddef&gt; [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":8313,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[370],"tags":[556,498],"class_list":["post-8311","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-17","tag-allocator","tag-memory"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8311","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=8311"}],"version-history":[{"count":28,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8311\/revisions"}],"predecessor-version":[{"id":8432,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8311\/revisions\/8432"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/8313"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=8311"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=8311"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=8311"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}