3 ms·
Fair enough: struct hamt_allocator { void *(*realloc)(struct hamt_allocator *h, void *chk, size_t oldsize, size_t newsize);
by cataphract 3y ago
Fair 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.