[plt-scheme] Question about _gcpointer and _cvector

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Nov 11 16:27:47 EST 2009

At Wed, 11 Nov 2009 14:57:22 -0600, "Will M. Farr" wrote:
> I have a question that (I think) the manual doesn't answer regarding the 
> interaction between _gcpointer and _cvector in the foreign interface.  Suppose 
> I have a C routine that uses the scheme_malloc_... functions to create an 
> array of structs allocated under the control of the garbage collector.  Then I 
> do the following in the FFI:
> (define make-some-stuff 
>   (get-ffi-obj 'make_some_stuff my-library
>     (_fun (n-stuff : _ufixnum) -> (stuff-array _gcpointer) -> 
>           (make-cvector* stuff-array _stuff-pointer n-stuff))))
> Does the cvector object always know that the pointer it holds should be a 
> _gcpointer?

The wrapper allocated by `make-cvector*' above uses the pointer
representation (i.e., a Scheme value) that is bound to `stuff-array'.
Since that representation is based on `_gcpointer', it will retain the
underlying pointer in the correct way.

> Suppose I change the _gcpointer above to _pointer (which would be 
> a mistake, but understandable)---does the cvector notice? 

Yes, the resulting `_cvector' would be wrong.

> What about if the 
> memory is allocated using regular malloc, and I use _gcpointer above---is the 
> new cvector vulnerable to the same memory bug that led to the creation of 
> _gcpointer?  


> In short, does a cvector know about the _[gc]pointer status of 
> the memory block it holds?

No. `make-cvector*' just holds on to the representation of the pointer,
and the representation carries with it the GCability of the underlying

I think it would be helpful to revise the FFI docs to make a clear
distinction between a "foreign pointer" and "a Scheme value that
represents a foreign pointer", but I haven't yet had time to try that.

Not your question, but just in case it's an issue: You should make sure
that `_stuff-pointer' is based on `_gcpointer' and not on `_pointer',
since the individual pointers in the array produced by
make_some_stuff() refer to GCable memory. Otherwise, when you extract a
value from the array with `cvector-ref', the resulting pointer
representation will not correctly retain the pointer extracted from the
array. If `_stuff-pointer' happens to be defined by `(define-cstruct
_stuff ....)', then you should use `(_gcable _stuff-pointer)' instead
of `_stuff-pointer', since the `_stuff-pointer' defined by
`define-cstruct' will be based on `_pointer'.

Posted on the users mailing list.