(define o (get-foreign-wrapper ...)) ; a will has been created for o,
which will delete the underlying C data
(define t (make-table weak-values: #t)) (table-set! t 'o o) (set! o #f) (##gc)
At this point your foreign wrapper is not strongly reachable anymore. The garbage collection has triggered your will, which has freed the C object wrapped by o. But you can still
(println (table-ref t 'o))
And get an access to invalid memory or a segmentation fault.
Wait, what is returned by get-foreign-wrapper and are other references to it sticking around at that GC?
get-foreign-wrapper creates a foreign object with type (struct "something") and attachs a will to it that calls (e.g.) foreign-release! on it when executed. A complete, working example follows:
; test-invalid-access.scm ; ; Compile with ; ; gsc -cc-options -g -exe test-invalid-access.scm ; ; Test with ; ; valgrind ./test-invalid-access ; ; (Or some other memory usage checker.) ; ; Comment out last line to see that the program would otherwise never access ; invalid memory.
; BEGIN Library code
(c-declare "struct point {int x; int y;};")
(define (make-point x y) (let ((p ((c-lambda (int int) (struct "point") "struct point *p = (struct point*)___EXT(___alloc_rc)(sizeof(struct point)); p->x = ___arg1; p->y = ___arg2; ___result_voidstar = p;") x y))) (make-will p (lambda (x) (println "releasing " (point->string x)) (foreign-release! x))) p))
(define point-x (c-lambda ((struct "point")) int "___result = ((struct point*)___arg1_voidstar)->x;"))
(define point-y (c-lambda ((struct "point")) int "___result = ((struct point*)___arg1_voidstar)->y;"))
(define (point->string p) (string-append "point(" (number->string (point-x p)) ", " (number->string (point-y p)) ")"))
; END library code; BEGIN user code
(define p (make-point 1 2)) (define t (make-table weak-values: #t)) (table-set! t 'p p) (println "before releasing: " (point->string p)) (set! p #f) (##gc) (println "after releasing:") ; Comment out the following line and you get no invalid accesses. (println (point->string (table-ref t 'p)))
; END of example