4 ms·
You don't need the cookie then. You can just allocate a larger struct (sort of subclassing it). You save a pointer indirection.
by cataphract 3y ago
You don't need the cookie then. You can just allocate a larger struct (sort of subclassing it). You save a pointer indirection.
- thechao 3y agoThere's a limit to what can be crammed into a HN comment!
- pixelpoet 3y agoI have discovered a truly marvelous allocator pattern which this HN comment is too small to contain.
- jjgreen 3y ago[350 years later] I have confirmed the optimality of the allocator pattern as a special case in my proof of the Inter-universal Teichmüller theorem (Springer, 879pp).
- inopinatus 3y agoThe solution is obviously to realloc the comment.
- cataphract 3y agoFair enough: struct hamt_allocator { void *(*realloc)(struct hamt_allocator *h, void *chk, size_t oldsize, size_t newsize); }; struct my_allocator { struct hamt_allocator parent; size_t used; char buffer[8192]; }; static void *alloc_func(struct hamt_allocator *h, void *chk, const size_t oldsize, const size_t newsize) { if (!newsize) { return NULL; } if (h && newsize <= oldsize) { return h; } // this cast is allowed by the standard for this purpose __auto_type *alloc = (struct my_allocator*) h; if (newsize > sizeof(alloc->buffer) - alloc->used) { return NULL; } void *ret = alloc->buffer + alloc->used; alloc->used += newsize; if (h && oldsize) { memcpy(ret, h, oldsize); } return ret; } void func_taking_allocator(struct hamt_allocator *h); void user_code() { struct my_allocator alloc = { .parent.realloc = alloc_func }; func_taking_allocator(&alloc.parent); }
- mkirchner 3y agoBeautiful, thanks!
- cataphract 3y agoWhile this was not the point of the comment, one thing missing is that oldsize and newsize should be rounded for alignment purposes: struct my_allocator { struct hamt_allocator parent; size_t used; union { char buffer[8192]; max_align_t _align; }; }; static inline size_t align_size(size_t value) { size_t alignment = _Alignof(max_align_t); // if (value % _Alignof(max_align_t) == 0) { // return value; // } else { // return ((value / alignment) + 1) * alignment; // } return value + (alignment - 1) & ~(alignment - 1); } Even better, the allocator function should get the alignment so don't waste bytes unnecessarily.