Thanks to all who replied to me and especially to Olivier Andrieu for great ideas and discussion. Let me try to sum up what I understood as it may help others. The first and main misunderstanding I had was with Data_custom_val(v) which is a pointer TO the data space IN THE ALLOCATED CUSTOM BLOCK and not, for example, from the custom bloc to some data storage outside of it. So Data_custom_val(v) cannot be allocated, only *Data_custom_val(v) can. To be more precise, if one want to store some data of type 'mytype' into the custom block, one just has to do r = alloc_custom(&mytype_ops, sizeof(mytype), , ); *(mytype *) Data_custom_val(r) = ; In that case, mytype_ops.finalize does NOT have to free memory -- reclaiming the custom block does that. Now storing the data into the custom block is fine as long as one has good understanding of how the data is freed. For example, the bigarray module does that (at least is stores the C struct, not the actual data, in the custom block) but may not be suitable for more complicated structures or objects. For example, if the structure points to some other data, one must make sure that this data is not freed before the block is deleted. Indeed, if so, the block would still exist but trying to access the data would result in a segfault. For example, doing (1) objecttype *o = new objectype(); r = alloc_custom(&objectype_ops, sizeof(objectype), , ); *(objectype *) Data_custom_val(r) = *o; may be problematic since, when o will be freed, that may also free a lot of the data referenced by o and so *(objectype*)Data_custom_val(r) will only contain a copy to the "top" object. For the example given in http://caml.inria.fr/Hump/msg778-782 that is not a problem since the object is "self-contained". The drawback however is that this makes it impossible to have a global value. The implementation corresponding to that idea is in the file cell_stub1.cpp (and tested via 'make test1'). Given the above, it is better to only store a pointer to the onject in the custom bloc and thus to replace (1) with (2) r = alloc_custom(&objectype_ops, sizeof(objectype *), , ); *(objectype **) Data_custom_val(r) = new objectype(); This time however, freeing the custom block will not delete the object (only the pointer in the custom block) and so objectype_ops.finalize(value v) must contain delete (*(objectype **) Data_custom_val(v)); This idea is implemented in cell_stub.cpp (to test it, just type 'make'). All comments are welcome. Cheers, ChriS