[Openmcl-devel] Fix memory leak in an objc example

Leo Liu sdl.web at gmail.com
Sat May 3 00:09:58 PDT 2014


On 2014-04-30 21:48 -0400, R. Matthew Emerson wrote:
> You're confusing unrelated things.
>
> What rlet does is to allocate some memory on the stack.
>
> According to Apple's conventions, because _LSCopyAllApplicationURLs
> has the word "copy" in it, you "own" whatever it returns, and must
> release it when you're done with it.
>
> So, you might say
> (let ((array (%get-ptr urls)))
>   ;; use array
>   (#/release array) ;or (#_CFRelease array)
>
> The main difference between #/release and #_CFRelease is that the
> call to #_CFRelease will crash if you pass it a null pointer (as
> made by (ccl:%null-ptr) or +null-ptr+), and #/release won't.  As with
> all Objective-C methods, sending a message to a null pointer returns
> a null pointer.

Thank you rme for the help here and on #irc.

It seems I need to release every object that is placed in rlet's
pointers.

For example (full file attached):

(defun default-application (url)
  (objc:with-autorelease-pool
    (ccl:rlet ((appurl #>CFURLRef))
      (let* ((url (#/fileURLWithPath: ns:ns-url
                                      (ccl:with-encoded-cstrs :utf-8 ((s url))
                                        (#/stringWithUTF8String: ns:ns-string s))))
             (status (#_LSGetApplicationForURL
                      url #$kLSRolesAll ccl:+null-ptr+ appurl)))
        (when (zerop status)
          (nsurl-to-path (ccl:%get-ptr appurl)))))))

(progn (loop repeat 10000 do (default-application "/Applications/Contacts.app")) (ccl:gc))

Will increase the memory use by a few megabytes.

Leo

-------------- next part --------------
A non-text attachment was scrubbed...
Name: memleak.lisp
Type: application/x-emacs-lisp
Size: 1341 bytes
Desc: memleak.lisp
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20140503/713eb62d/attachment.bin>


More information about the Openmcl-devel mailing list