On Fri, May 24, 2013 at 1:42 PM, Phil Thompson <span dir="ltr"><<a href="mailto:phil@riverbankcomputing.com" target="_blank">phil@riverbankcomputing.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="HOEnZb"><div class="h5">On Thu, 23 May 2013 16:21:26 -0400, Luke Campagnola<br>
<<a href="mailto:lcampagn@email.unc.edu">lcampagn@email.unc.edu</a>> wrote:<br>
> Howdy,<br>
> I am using PyQt 4.10.1 (Py2.7-qt4.8.4-x32) on windows XP. It appears<br>
that<br>
> on this system, QImage(sip.voidptr, int, int, format) increases the<br>
> reference count to the image data object, but does not decrease the<br>
> refcount after the QImage is collected. Here's an example session, where<br>
I<br>
> am generating a QImage from a numpy array:<br>
><br>
>>>> from PyQt4 import QtGui<br>
>>>> import ctypes, weakref, sys<br>
>>>> import numpy as np<br>
>>>> data = np.zeros((100,100,4), dtype=np.ubyte)<br>
>>>> addr = ctypes.c_char.from_buffer(data,0)<br>
>>>> sys.getrefcount(addr)<br>
> 2<br>
>>>> img = QtGui.QImage(addr, 100, 100, QtGui.QImage.Format_ARGB32)<br>
>>>> sys.getrefcount(addr)   # QImage added 1 to reference count<br>
> 3<br>
>>>> import weakref<br>
>>>> ref = weakref.ref(img)<br>
>>>> del img<br>
>>>> ref<br>
> <weakref at 0161F090; dead>  # QImage was collected<br>
>>>> sys.getrefcount(addr)  # but refcount is still 3<br>
> 3<br>
><br>
><br>
> Can anyone recommend a good way to convert from ndarray to QImage<br>
> (preferrably without incurring any memory copy) ?<br>
<br>
</div></div>Using either a sip.voidptr or a string seems to work fine for me with<br>
current snapshots.<br></blockquote><div><br></div><div><div>Thanks, Phil. I'd like to revisit this (as well as an older, related question) a bit since we're still having trouble with them. I've boiled the problem down a bit more and it appears entirely within sip.voidptr (or my usage of sip.voidptr). First, the control, running under 4.9.3:</div>

<div><br></div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_quote"><div><div>import sip, numpy, gc</div></div></div><div class="gmail_quote"><div><div>arr = numpy.zeros(100000000, dtype=numpy.ubyte)</div>

</div></div><div class="gmail_quote"><div><div>ptr = sip.voidptr(arr.ctypes.data)</div></div></div><div class="gmail_quote"><div><div>del arr, ptr</div></div></div><div class="gmail_quote"><div><div>gc.collect()</div></div>

</div></blockquote><div class="gmail_quote"><div><div><br></div><div>This code runs as expected. Note that the argument to sip.voidptr is an integer, the memory address of the array data.</div><div>Now the trouble, running under 4.10.2:</div>

<div><br></div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_quote"><div><div>import sip, numpy, gc</div></div></div><div class="gmail_quote"><div><div>arr = numpy.zeros(100000000, dtype=numpy.ubyte)</div>

</div></div><div class="gmail_quote"><div><div>ptr = sip.voidptr(arr)</div></div></div><div class="gmail_quote"><div><div>del arr, ptr</div></div></div><div class="gmail_quote"><div><div>gc.collect()</div></div></div></blockquote>

<div class="gmail_quote"><div><div><br></div><div>This code leaks the 100MB array. If I inspect with sys.getrefcount, I see that the array has picked up some extra counts that were not removed after the voidptr is deleted. Note also that the argument to sip.voidptr here is the numpy array itself. If I try passing an integer to sip.voidptr under 4.10.2, I get the error "TypeError: a single integer, Capsule, CObject, None, buffer protocol implementor or another sip.voidptr object is required". Likewise, I get the same error if I pass the array directly to sip.voidptr under 4.9.3. </div>

<div><br></div><div>So I have two questions about this code:</div><div><br></div><div>1) Is there some way to avoid the memory leak in 4.10.2?</div><div>2) Can you tell me when the API change to sip.voidptr occurred? </div>

<div><br></div><div>Thanks very much! I really appreciate the effort and support you have put into this project. </div></div><div><br></div><div><br></div><div>Luke</div></div>