[Haskell-cafe] FFI nested structs - malloc - free
rasen.dubi at gmail.com
Mon May 11 06:47:18 UTC 2015
First note: it's not GCC, but Haskell's GC.
Second, I believe it's not necessary to put strict annotations because all
function parameters are evaluated before calling FFI function. It's just a
general good practice to make all data fields strict unless there are
reasons to do otherwise.
On Sun, May 10, 2015, 18:58 Proclivis <mike at proclivis.com> wrote:
> Thanks guys,
> I looks like there are basically 2 ways to do this:
> 1) Build a structure of ForeignPtr with finalizers that will be freed
> whenever the GCC feels like it
> 2) Nest allocations and the will free at the end of IO
> I noticed that in Real World Haskell the example of #1 has a ForeignPtr
> and ByteString in a data constructor, and both are bang noted as strict. Is
> this required before passing the data to a C-call to ensure it is evaluated
> or just a choice with the usual implications, such that with or without the
> evaluation of the C-call is well behaved?
> Sent from my iPad
> On May 5, 2015, at 10:10 AM, Michael Steele <mikesteele81 at gmail.com>
> It looks like memory cleanup is being ignored in the example you linked
> to. newCString and mallocArray do not automatically free memory.
> When building nested structures simply in order to pass them to a few C
> functions, I like to use with* and alloca* functions whenever possible.
> The following (untested) example temporarily marshals a C structure
> containing 2 pointers to null-terminated strings, and passes that to a
> supplied action. 4-byte pointers and ints are assumed:
> > data Person = Person String String Int
> > withPerson :: Person -> (Ptr Person -> IO r) -> IO r
> > withPerson (Person fn ln age) f =
> > -- Haskell's layout rules allow you to line these all up vertically.
> > -- Just place all your allocations before the first 'do'.
> > withCString fn $ \pfn ->
> > withCString ln $ \pln ->
> > allocaBytes 12 $ \ptr -> do
> > pokeByteOff ptr 0 pfn
> > pokeByteOff ptr 4 pln
> > pokeByteOff ptr 8 age
> > f ptr
> In cases where you can't know ahead of time when the memory should be
> freed, you an use ForeignPtr. I think Real World Haskell gives an example
> of a nested structure marshaled in this way. By storing the ForeignPtr in a
> data object that gets carried around, you can guarantee that finalizes get
> called by the garbage collector only after you are done using them.
> I hope that helps.
> -- Michael Steele
> On Tue, May 5, 2015 at 6:22 AM, Michael Jones <mike at proclivis.com> wrote:
>> That is an interesting insight. I suppose there are C API like that.
>> In my case, the FFI calls ioctl, which calls i2cdev_ioctl, which calls
>> The only function that can assume anything about the structure is
>> i2cdev_ioctl_rdwr, which as you can see below copies the data, but does not
>> free it.
>> So in this particular case, I need the FFI to free it.
>> On the other hand, I could write a wrapper in C that frees the structure
>> if that is the way FFI is supposed to be used.
>> Does anyone know if there is a FFI solution that would not require a
>> static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
>> unsigned long arg)
>> struct i2c_rdwr_ioctl_data rdwr_arg;
>> struct i2c_msg *rdwr_pa;
>> u8 __user **data_ptrs;
>> int i, res;
>> if (copy_from_user(&rdwr_arg,
>> (struct i2c_rdwr_ioctl_data __user *)arg,
>> return -EFAULT;
>> On May 4, 2015, at 10:40 PM, Alexey Shmalko <rasen.dubi at gmail.com> wrote:
>> > Hi!
>> > Disclaimer: I haven't worked much with FFI, so I'd like someone
>> > confirmed my words.
>> > Seems that allocated memory in your example is supposed to be freed
>> > from inside C. It's not a memory leak.
>> > If I understand correctly documentation , malloc/free are just a
>> > simple wrappers around C's malloc/free. It's mallocForeignPtr that
>> > sets finalizer.
>> > Best regards,
>> > Alexey Shmalko
>> > :
>> > On Tue, May 5, 2015 at 6:45 AM, Proclivis <mike at proclivis.com> wrote:
>> >> I should have mentioned GHC 7.8.3 Ubuntu 64bit
>> >> Sent from my iPad
>> >>> On May 4, 2015, at 9:42 PM, Proclivis <mike at proclivis.com> wrote:
>> >>> FFI Gurus,
>> >>> I created a c2hs FFI of a nested C structure, where struct A has a
>> pointer to a struct B. To do so, I used a malloc, but I am unsure if the
>> memory will be freed when the resulting Ptr is freed.
>> >>> The example at this link uses the same technique, so it will serve as
>> an example.
>> >>> Line 48 and 51 do the malloc and assign the pointer in the struct,
>> from inside a Storable poke implementation.
>> >>> But, there is no explicit free, nor a finalizer.
>> >>> Will the memory be freed when the Ptr of the Storable is freed?
>> >>> If it is, it implies that some magic keeps track of mallocs inside a
>> poke, and creates finalizers. Or, this example leaks. If it leaks, how do I
>> create a finalizer from inside a poke implementation?
>> >>> Mike
>> >>> _______________________________________________
>> >>> Haskell-Cafe mailing list
>> >>> Haskell-Cafe at haskell.org
>> >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>> >> _______________________________________________
>> >> Haskell-Cafe mailing list
>> >> Haskell-Cafe at haskell.org
>> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
> -- Michael Steele
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe