Re: cdata upvalue and garbage collection

  • From: Laurent Deniau <Laurent.Deniau@xxxxxxx>
  • To: "luajit@xxxxxxxxxxxxx" <luajit@xxxxxxxxxxxxx>
  • Date: Mon, 3 Oct 2016 14:00:44 +0000

On 03 Oct 2016, at 15:50, Peter Cawley <corsix@xxxxxxxxxx> wrote:

On Mon, Oct 3, 2016 at 2:43 PM, Laurent Deniau <Laurent.Deniau@xxxxxxx> wrote:
I am a bit confused about what you say here. Given the following code:

ffi.cdef [[
 typedef struct { int32_t nr, nc; double data[?]; }  matrix_t;
]]

local matrix_ctor = ffi.typeof 'matrix_t'
local matrix_cref = ffi.typeof 'matrix_t&'

local function matrix_alloc (len)
 local siz = ffi.sizeof(matrix_ctor, len)
 local ptr = C.malloc(siz)
 mat = ffi.gc(ffi.cast(matrix_cref, ptr), C.free)
 return mat
end

Assuming that mat is used (hooked) after the return, does it mean that the
memory pointed by ptr and allocated by C malloc can be GCed (calling free)
because the ffi.cast does not keep any reference? If it is the case, how do
I prevent this?

Note the difference between `ffi.new` and `ffi.C.malloc`. In the
former, the cdata "owns" the allocated memory, and the cdata must be
kept alive, else the GC will free the memory. In the latter, there are
actually two allocations, a pointer-sized cdata (in the Lua heap) and
a memory blob (in the C heap). You can cast the cdata and forget the
original cdata, at which point the original cdata will be GCed at some
point, but as it doesn't own the memory blob in the C heap, everything
is fine.

Thanks for the clarification, I get it.


Other related posts: