Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What precautions should I take to make a memory pool that does not invoke undefined behavior?

My initial problem is that I have, on a project, several objects which share a lifetime (i.e., once I free one of them, I'll free them all), then I wanted to allocate a single block of memory. I have arrays of three different object types, struct foo, void *, and char. At first I wanted to malloc() a block like this:

// +---------------+---------+-----------+---------+---------+ // | struct foo[n] | padding | void *[m] | padding | char[o] | // +---------------+---------+-----------+---------+---------+ 

But then... how could I accomplish this without invoking undefined behavior? I.e., respecting type aliasing rules, aligment... How to properly calculate the memory block size, declare the memory block (with its effective type), and how to properly get pointers to all three sections within it portably?

(I do understand I could malloc() 3 blocks, which would result in three free(), but I'd like to know how to do it with a single block while still well-behaved.)

I'd like to extend my problem to a more general question: what precautions should one take to implement a memory pool for objects with arbitrary sizes and alignment while keeping the program well-behaved? (Assuming it is possible to implement it without invoking undefined behavior.)

like image 405
paulotorrens Avatar asked Sep 22 '16 13:09

paulotorrens


1 Answers

However hard you try, it's not possible to implement malloc in pure C.

You always end up violating strict aliasing at some point. For the avoidance of doubt, using a char buffer that doesn't have dynamic storage duration will also violate strict aliasing rules. You would also have to make sure that any pointer returned has an appropriate alignment.

If you're happy to tie yourself down to a particular platform then you may as well turn to that particular implementation of malloc for inspiration.

But why not consider writing a stub function which calls malloc and also builds up a table of other allocated objects? You could even implement some kind of observer / notify framework. Another starting point could be well-known garbage collectors that have been written in C.

like image 139
Bathsheba Avatar answered Oct 11 '22 21:10

Bathsheba