Recently, I made a new friend. His name is _expand, and we've had some nice conversations, and I've even hung out with him a few times. But when I started asking around, no one had ever heard of my _expand. I became suspicious. I called a few thoroughly non-metaphorical friends at microsoft, and a few friends elsewhere in the business. Nothing. No one had ever used it. I noodled around various search engines and source trees. Nothing except a cursory mention here and there. Certainly not enough information on performance and compatibility for me to introduce _expand into production code or more pertinently, generic libraries.
Worse, there's no equivalent function that I can find in any of the gnu libraries, so anything I hack up with my new friend isn't going to be portable in the least. Which is a shame, because it's really a fascinating and exciting capacity to have. Certainly, I could dig down into realloc, and pull apart how it functions, but the problem there is that much of the implementation is highly variable on *nixes. So I'd have to code version after version to try and get a portable _expand. Still, it seems ridiculous that nothing similar exists in the glib or the expanded gnu libs.
To clarify my interests, I'm trying to build a singly-linked accumulator that expands in an attempt to minimize fragmentation while allocating multiple-element blocks along the lines of the traditional deque implementation. By constraining the use-cases for element addition and deletion, I'm hoping to optimize time-to-delete for the whole structure, as well as element insertion and indexing. As a result, the "loud failure" of _expand lets me make the structure think intelligently about when and if it can resize inplace, and what that means about where it can put data.
That C++ has been getting by with new
and delete
sans any equivalent of realloc
shows how little attention these things get. Unsurprising _expand
is largely ignored when it's not even consistently available at the OS level. If you want to roll your own, there's plenty of precedent for user-defined versions of malloc, and a quick look in /usr/include/malloc.h on my Linux box shows hooks explicitly for this...
/* Called once when malloc is initialized; redefining this variable in
the application provides the preferred way to set up the hook
pointers. */
extern void (*__malloc_initialize_hook) __MALLOC_PMT ((void));
/* Hooks for debugging and user-defined versions. */
extern void (*__free_hook) __MALLOC_PMT ((__malloc_ptr_t __ptr,
__const __malloc_ptr_t));
extern __malloc_ptr_t (*__malloc_hook) __MALLOC_PMT ((size_t __size,
__const __malloc_ptr_t));
extern __malloc_ptr_t (*__realloc_hook) __MALLOC_PMT ((__malloc_ptr_t __ptr,
size_t __size,
__const __malloc_ptr_t));
extern __malloc_ptr_t (*__memalign_hook) __MALLOC_PMT ((size_t __alignment,
size_t __size,
__const __malloc_ptr_t));
extern void (*__after_morecore_hook) __MALLOC_PMT ((void));
Doesn't look like you'll be able to intercept the existing realloc
implementation at that particular decision point though, or easily get insight into whether it will resize inplace, so you might have to reimplement everything (or adapt any of many existing heap implementations).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With