[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: small problem with LuaJIT FFI and gc method
- From: Mike Pall <mikelu-1103@...>
- Date: Tue, 15 Mar 2011 18:40:44 +0100
Francesco Abbate wrote:
> I'm using ffi.cdef for the following struct/functions:
>
> ---------
> typedef struct
> {
> size_t size;
> size_t *data;
> } gsl_permutation;
>
> gsl_permutation *gsl_permutation_calloc (const size_t n);
> void gsl_permutation_init (gsl_permutation * p);
> void gsl_permutation_free (gsl_permutation * p);
> --------------
Why do you need to use C calls for that? Assuming the data part
doesn't grow after allocation you could use a variable-length
struct instead:
ffi.cdef[[
typedef struct {
size_t size;
size_t data[?];
} gsl_permutation;
]]
local p = ffi.new("gsl_permutation", 5)
p.size = 5
This nicely avoids the GC issues, too.
BTW: The use of size_t for anything but actual memory sizes is not
a good idea. I guess int32_t would be a much better fit here.
> p = ffi.C.gsl_permutation_calloc(5)
> ffi.gc(p, ffi.C.gsl_permutation_free)
It doesn't make a difference here, but always use it like this:
local p = ffi.gc(ffi.C.gsl_permutation_calloc(5), ffi.C.gsl_permutation_free)
> where p is actually a local variable. The problem is that in this case
> I can get memory corruption and it seems that it happens when p is
> garbage-collected. I don't understand why... I'm doing something wrong?
Either you're dropping the last reference to p too early or
something is wrong with the deallocation function.
> The following variant seems to work:
>
> p = ffi.new('gsl_permutation[1]')
> local data = ffi.new(string.format('size_t[%i]', nr))
Uh, why this? Neither do you need to create a 1-element array of a
struct, nor is there any necessity to use string.format for a
variable-length array:
local p = ffi.new("gsl_permutation")
local data = ffi.new("size_t[?]", nr)
> but in this case there is a problem: luajit is not aware that p
> depends on data and so it can collect data when p is still around. I
> was able to find a solution by storing the cdata objects in a table
> but I'm wondering what is the best method to do that correctly.
Keep it in one combined (variable-length) struct. Or use a plain
Lua table for more complex linked data structures. It's unlikely
to make much of a difference, except for big arrays.
--Mike