Here's the core of your code, without the extra noise:
#lang racket
(require ffi/unsafe)
(define-cstruct _rect ([x _int] [y _int] [w _int] [h _int]))
(let loop ([n 0])
(make-rect 0 0 1 1)
;; (list 0 0 1 1)
(displayln (current-memory-use))
(loop (add1 n)))
If you run it, you'll see what looks like a leak. Now flip the comments to use list
and you'll see a similar leak. The thing is that you're printing the memory use after each an every allocation, and it takes a good while to reach a point where the GC starts working. If you change it to do the printout less frequently, you'll see a stable memory. Here's what I run to see this:
#lang racket
(require ffi/unsafe)
(define-cstruct _rect ([x _int] [y _int] [w _int] [h _int]))
(let loop ([n 0])
(make-rect 0 0 1 1)
(when (zero? (modulo n 100000)) (displayln (current-memory-use)))
(loop (add1 n)))
That being said, it is easy to get memory leaks when you're using the unsafe FFI, and you're using a library that might a problem itself, and after all of that, it might be that there's some other bug...