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