Wrap C allocation for RAII

…衆ロ難τιáo~ 提交于 2019-12-05 05:16:43

Yes, you can reuse unique_ptr for this. Just make a custom deleter.

struct salloc_deleter {
    void operator()(SAlloc* s) const {
        free_salloc(s); // what the heck is the return value for?
    }
}

using salloc_ptr = std::unique_ptr<SAlloc, salloc_deleter>;

I like R. Martinho Fernandes' answer, but here's a shorter (but less efficient) alternative:

auto my_alloc = std::shared_ptr<SAlloc>(new_salloc(), free_salloc);

Is there any way I can wrap this in C++ to a smart pointer (std::unique_ptr), or otherwise a RAII wrapper ?

Yes. You need here a factory function, that creates objects initializing the smart pointer correctly (and ensures you always construct pointer instances correctly):

std::shared_ptr<SAlloc> make_shared_salloc()
{
    return std::shared_ptr<SAlloc>(new_salloc(), free_salloc);
}

// Note: this doesn't work (see comment from @R.MartinhoFernandes below)
std::unique_ptr<SAlloc> make_unique_salloc()
{
    return std::unique_ptr<SAlloc>(new_salloc(), free_salloc);
}

You can assign the result of calling these functions to other smart pointers (as needed) and the pointers will be deleted correctly.

Edit: Alternately, you could particularize std::make_shared for your SAlloc.

Edit 2: The second function (make_unique_salloc) doesn't compile. An alternative deleter functor needs to be implemented to support the implementation.

Another variation:

#include <memory>

struct SAlloc {
  int x;
};
SAlloc *new_salloc() { return new SAlloc(); }
void   free_salloc(SAlloc *s) { delete s; }

struct salloc_freer {
  void operator()(SAlloc* s) const { free_salloc(s); }
};
typedef std::unique_ptr<SAlloc, salloc_freer> unique_salloc;
template<typename... Args>
unique_salloc make_salloc(Args&&... args) {
  auto retval = unique_salloc( new_salloc() );
  if(retval) {
    *retval = SAlloc{std::forward<Args>(args)...};
  }
  return retval;
}

int main() {
   unique_salloc u = make_salloc(7);
}

I included a body to SAlloc and the various functions to make it a http://sscce.org/ -- the implementation of those doesn't matter.

So long as you can see the members of SAlloc, the above will let you construct them like in an initializer list at the same time as you make the SAlloc, and if you don't pass in any arguments it will zero the entire SAlloc struct.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!