mercredi 26 juillet 2017

Memory-efficient custom deleter for std::unique_ptr?

This may be a bit implementation-specific, but some of it seems fundamental.

I'm certain I must be missing something in the standard library.

The problem is this:

I want to implement a std::unique_ptr whose deleter is free()

[ because the value is allocated via malloc() ]

There are, of course, lots of options on how to do this, but (at least in g++ 4.8.4 for x86-64) they appear to have different memory usage implications.

E.g.: Method 1:

std::unique_ptr<char, std::function<void(void*)>> ptr_a(malloc(10), free);

However, sizeof(ptr_a) == 40 bytes (8 for void*, 32 for std::function<>)

Method 2:

std::unique_ptr<void, void (*)(void*)> ptr_b(malloc(10), free);

Somewhat better, as sizeof(ptr_b) == 16 bytes (8 for void*, 8 for bare function pointer ])

Method 3:

template <void (*T)(void*)>
class Caller {
 public:
  void operator()(void* arg) {
    return T(arg);
  }
};
std::unique_ptr<void, Caller<free>> ptr_c(malloc(10));`

At this point, sizeof(ptr_c) == 8 bytes (the minimum possible) - but I've had to introduce a class that's pretty much pure boilerplate (and, as shown, easily templatized).

This seems like such a simple pattern - is there some element in the STL that does what Caller<> does above?

Of course, g++ by default does indeed appear to free() when calling delete on a trivial type - but this seems far from guaranteed by the standard (if nothing else, new/delete may be redefined from the default allocation/deallocation functions, and default_delete would then call the replacement delete).

And plus, there are other cases where the release of some object allocated in a pure-C library would be implemented by a simple function call, rather than a deleter. It seems somewhat tedious to have to wrap such allocation/deallocation functions in classes in order to get std::unique_ptr to call them both correctly and efficiently - which makes me think I'm missing something (most of the rest of the modern C++ specs seem to be extremely well thought out).

Aucun commentaire:

Enregistrer un commentaire