[ocaml-ctypes] Lifetime of Ctypes allocation

Jeremy Yallop yallop at gmail.com
Tue Apr 19 11:33:02 BST 2016


On 18 April 2016 at 23:02, Markus Müller <llmarkvm at gmail.com> wrote:
> open Ctypes
> open Foreign
> let f = foreign "f" ((ptr (ptr int)) @-> returning void)
> let v = ref (from_voidp (ptr int) null)
> let a = ref (from_voidp int null)
> let b = ref (from_voidp int null)
> let _ =
>   v := allocate_n (ptr int) ~count:2 ;
>   a := allocate int 0 ;
>   b := allocate int 1 ;
>   (!v) <-@ (!a);
>   ((!v) +@ 1) <-@ (!b) ;
>   f (!v) ; Gc.full_major () ; f (!v)
>
> and the following program is fine too.
>
> open Ctypes
> open Foreign
> let f = foreign "f" ((ptr (ptr int)) @-> returning void)
> let v = allocate_n (ptr int) ~count:2
> let a = allocate int 0
> let b = allocate int 1
> let _ =
>   v <-@ a;
>   (v +@ 1) <-@ b ;
>   f v ; Gc.full_major () ; f v
>
> However, having v, a, b in a local scope does not work.
>
> open Ctypes
> open Foreign
> let f = foreign "f" ((ptr (ptr int)) @-> returning void)
> let _ =
>   let v = ref (from_voidp (ptr int) null) in
>   let a = ref (from_voidp int null) in
>   let b = ref (from_voidp int null) in
>   v := allocate_n (ptr int) ~count:2 ;
>   a := allocate int 0 ;
>   b := allocate int 1 ;
>   (!v) <-@ (!a);
>   ((!v) +@ 1) <-@ (!b) ;
>   f (!v) ;
>   Gc.full_major () ;
>   f (!v)
>
> I fail to see why it does not work in this case.

The GC is free to collect values that are no longer reachable by the
program, even if there are references to them still "in scope".  Since
'a' is not used after the call to Gc.full_major, the collector can
ignore 'a' when determining whether values are reachable.  Here's a
simpler program that illustrates the same behaviour

   let say_goodbye _ = print_endline "goodbye"

   let _ =
     let r = ref (object end) in
     Gc.finalise say_goodbye !r;
     Gc.full_major ();
     print_endline "the end"

On my system this prints

   goodbye
   the end

i.e. the object is finalised by the call to Gc.full_major, even though
'r' is still in scope.  Since 'r' is not used after the call, this
behaviour is entirely legitimate.

I think that using 'allocate' works best when you're actually using
the pointer it returns to address the memory it allocates.  The need
to use delicate tricks to keep the allocated memory alive is often a
sign that a different allocation strategy would be a better choice.
The choice of strategy will depend on how your application uses
memory.

Kind regards,

Jeremy.


More information about the Ctypes mailing list