title: Custom allocator for std::vector<> with release?
body: <p>I am working with a 3rd party C API set in C++ that has two methods of concern for this discussion:</p>
  
  <ol>
  <li>It's equivalent of malloc(): <strong>the_api_malloc(size)</strong> (plus a matching the_api_free())</li>
  <li>A function in which memory created with the_api_malloc() is returned to that takes ownership of it and the_api_free()'s it internally: <strong>the_api_give_back(ptr)</strong></li>
  </ol>
  
  <p>I have created a custom allocator wrapping the_api_malloc() and the_api_free() to use with for example std::vector. This works great.</p>
  
  <p>What I'd like to do is have a std::vector type class that utilizes my custom allocator but also has a release() method that when called, releases ownership of it's memory and therefor will not call my custom allocators the_api_free().</p>
  
  <pre><code>pointer release() /* pointer is of T* */
  </code></pre>
  
  <p>Example usage:</p>
  
  <pre><code>MyClass myClass(1024); // the_api_malloc()'s 1024 bytes
  // ... do something with myClass
  the_api_give_back(myClass.release());
  </code></pre>
  
  <p>I'm not sure the best way to pull this off. What I have right now as a experiment is rather nasty:</p>
  
  <pre><code>class MyClass : public std::vector&lt;char, MyAllocator&lt;char&gt; &gt; {
  public:
      using typename std::vector&lt;char, MyAllocator&lt;char&gt; &gt;::pointer;
  
      pointer release() {
          // note: visual studio impl.
          pointer p = this-&gt;_Myfirst;
          this-&gt;_Myfirst = 0;
          this-&gt;_Mylast = 0;
          this-&gt;_Myend = 0;
          return p;
      }
  }
  </code></pre>
  
  <p>Is there a better way?</p>
  
  <p><strong>UPDATE 1</strong>: Here is what I've tried based on suggestions below. This should also help illustrate desired behavior &amp; where it is currently failing.</p>
  
  <pre><code>template &lt;class T&gt;
  class MyAllocator
  {
  public:
    // types omitted for clarity
  
    MyAllocator() : m_released(false) { }
  
    template &lt;class U&gt;
    MyAllocator(MyAllocator&lt;U&gt; const&amp; a) : m_released(a.m_released) { }
  
    // other ctors, dtors, etc. omitted for clarity
  
    // note: allocate() utilizes the_api_malloc()
  
    void deallocate(pointer p, size_type num)
    {
      if(!m_released) {
        the_api_free(p);
      }
    }
  
    void release_ownership() { m_released = true; }
  
    bool m_released;
  };
  
  template &lt;typename T&gt;
  char* ReleaseOwernship(T&amp; container)
  {
    container.get_allocator().release_ownership();
    return &amp;container[0];
  }
  
  // usage:
  { // scope
    std::vector&lt;char, MyAllocator&lt;char&gt; &gt; vec;
  
    // ...do something to populate vec...
  
    char* p = ReleaseOwnership(vec);
    the_api_give_back(p); // this API takes ownership of p and will delete it itself
  } // end scope - note that MyAllocator::deallocate() gets called here -- m_release is still false
  </code></pre>
  
  <p><strong>UPDATE 2:</strong> Tried creating a MyOwningAllocator and a MyNonOwningAllocator then swapping from the owning to the non-owning where at "release time", but can't get swap() to work as they are different types.</p>