Wolfgang Pupp wrote: > local typeof, sizeof = ffi.typeof, ffi.sizeof > > local malloc > do > local libc, fill, cast, gc = ffi.C, ffi.fill, ffi.cast, ffi.gc > malloc = function(ctype) > local ptr = cast(typeof('$ *', ctype), libc.malloc(sizeof(ctype))) > fill(ptr, sizeof(ctype)) --zero-fill > gc(ptr, libc.free) > return ptr > end > end Umm ... 1. Don't use ffi.typeof() in a fast path. 2. Be careful when creating parameterized types repeatedly. Ok, so pointer types happen to be interned, but others aren't. If not interned, it'll create a distinguished ctype every time. You don't want that, since the JIT-compiler always specializes to a ctype. 3. Separating declaration and assignment of a local function kills the immutable upvalue optimization (e.g. when it's called from within another function after that). Don't do that. The way to design such an API is to use a factory function: local C, cast, fill, gc = ffi.C, ffi.cast, ffi.fill, ffi.gc local function malloc_type(ct) local ctp, cts = ffi.typeof("$ *", ct), ffi.sizeof(ct) return function() local p = cast(ctp, C.malloc(cts)) fill(p, cts) return gc(p, C.free) end end local point_new = malloc_type(PointF) local function whatever() local p1 = point_new() local p2 = point_new() ... end But note you always pay for the allocation of the GC-managed pointer object, anyway. Such a use of malloc() only makes sense if the allocated types are very large. Otherwise it's just an arduous ffi.new(). --Mike