Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I wrap a C object in a custom RAII Class in C++?

I am using the library igraph and the library uses a lot of allocating and freeing memory using custom functions. I want to remove the possibility of forgetting to free memory by using RAII.

The code beforehand looks something like this:

void doSomething() {
   igraph_vector_t shortest_path;

   igraph_get_shortest_path_dijkstra(
      someargs...,
      &shortest_path
      someargs...
   )

   igraph_vector_destroy(&shortest_path);
};

I want to replace igraph_vector_t with a custom C++ class that has a destructor that calls igraph_vector_destroy so I can just do:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

void doSomething() {
   raii_igraph_vector_t shortest_path;

   igraph_get_shortest_path_dijkstra(
      someargs...,
      &shortest_path
      someargs...
   )

I can make a custom class/struct like:

struct raii_igraph_vector_int {
    igraph_vector_int_t vec;
    ~RAIIVectorInt(){
        igraph_vector_int_destroy(&vec);
    }
};

And I can pass it into the function like:

   igraph_get_shortest_path_dijkstra(
      someargs...,
      &shortest_path**.vec**
      someargs...
   )

However, I was wondering if there was a way to not need to add on the .vec and just treat it as if it were the previous type.

>Solution :

This should do the trick (totally untested, though):

struct DeleteIGraphVector {
  void operator() (igraph_vector_t *vec) const {
    igraph_vector_destroy(vec);
    delete vec;
  }
};

using raii_igraph_vector_t = std::unique_ptr<igraph_vector_t, DeleteIGraphVector>;

void doSomething() {
  raii_igraph_vector_t shortest_path = new igraph_vector_t;
  
  igraph_get_shortest_path_dijkstra(
    someargs...,
    shortest_path,
    someargs...
  );
}

It uses unique_ptr with a custom deleter to destroy and then delete the igraph type appropriately. One disadvantage of this approach is that the igraph_vector_t will be heap-allocated, though. This could be avoided with unique_resource, which hasn’t quite made it into the C++ standard yet but is available in third-party libraries.

If you don’t want to write different deleters for each igraph type, you could try using templates.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading