One of my favorite aspects of unique_ptr
is the automatic memory management it provides. I would like to use unique_ptr
with something like a GSL vector.
However, gsl_vector
has its own mechanism for freeing memory (gsl_vector_free
). Is there a way to force the unique pointer to use GSL's vector freeing method? Valgrind (correctly) reports a mismatched use of malloc/delete when creating a unique_ptr<gsl_vector>
below:
#include <memory>
#include <gsl/gsl_vector.h>
void mem_gsl() {
gsl_vector *vec;
vec = gsl_vector_calloc(2);
gsl_vector_set(vec, 0, 2.0);
printf("%f\n", gsl_vector_get(vec, 0));
gsl_vector_free(vec); // Without this, there is a memory leak.
}
void mem_unique_ptr() {
std::unique_ptr<gsl_vector> vec;
vec.reset(gsl_vector_calloc(2));
// Using .get() each time I want to use the gsl_vector seems like overhead.
gsl_vector_set(vec.get(), 0, 2.0);
printf("%f\n", gsl_vector_get(vec.get(), 0));
// Valgrind correctly reports a mismatched use of delete and free.
}
int main(int argc, char *argv[]) {
mem_gsl();
mem_unique_ptr();
return 0;
}
Additionally, having to call get()
each time I want to access a vector element seems rather tedious. Is there a way around this?
You can do it by providing
std::unique_ptr
with a custom deleter. Something like this would probably do:To avoid the
.get()
calls and other boilerplate associated with wrapping agsl_vector
in aunique_ptr
, you could create a small RAII wrapper.This not only avoids boilerplate, but also allows you to easily extend functionality, say for instance, adding a constructor that takes a
std::initializer_list<double>
so you can construct and initialize the vector in a single expression.Live example
Having a make_unique_gsl_vector amd a custom deleter: