This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: PyMemoryView_FromBuffer memory leak
Type: Stage: resolved
Components: Versions:
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: lazka, skrah
Priority: normal Keywords:

Created on 2017-05-31 16:35 by lazka, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (7)
msg294851 - (view) Author: Christoph Reiter (lazka) * Date: 2017-05-31 16:35
I'm using the following code

PyObject *
get_memoryview (PyObject *self) {
    Py_buffer view;

    ...

    // this takes a ref on self
    if (PyBuffer_FillInfo (&view, self, buffer, length, 0, 0) < 0)
        return NULL;

    // this returns a <memory> object
    return PyMemoryView_FromBuffer (&view);
}

The problem is that when I call release() on the returned memory object
the buffer does not get release and as a result the exporter leaks.

Am I missing something or is this a bug?
msg294852 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2017-05-31 17:05
"Py_buffer view" is stack allocated. One can use memoryviews based on such buffers *inside* a function, but not return them.
msg294853 - (view) Author: Christoph Reiter (lazka) * Date: 2017-05-31 17:10
hm, ok.

Any idea how I can create a memoryview that is usable from Python then?
msg294856 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2017-05-31 17:23
"Py_buffer view" needs to go into the exporting object.  That object needs  a getbufferproc().  That getbufferproc() can use  PyBuffer_FillInfo() to fill in the view that is now kept alive because it's in the object.

The object then supports the buffer protocol and memoryviews can be created automatically from the Python level without any further C code.
msg294858 - (view) Author: Christoph Reiter (lazka) * Date: 2017-05-31 17:32
Ah, so if I understand correctly, exposing always requires something implementing the buffer interface in some way. I might require multiple different memoryviews for this object, so maybe some proxy object implementing it might work.

Thanks Stefan for your quick help.
msg294860 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2017-05-31 17:35
Sorry, actually I wasn't totally clear:  The exporting object just needs a getbufferproc() that can respond to buffer requests and keeps track of how many views are exported.

"View in the object" is misleading and not necessary; it can be used for some advanced stuff.
msg294867 - (view) Author: Christoph Reiter (lazka) * Date: 2017-05-31 19:49
In case someone ends up here with a similar problem, here is my solution using a proxy object: https://github.com/pygobject/pycairo/blob/4ab80df68dd99a8e4bfb0c6a88dc5b2a9b0f3f10/cairo/bufferproxy.c
History
Date User Action Args
2022-04-11 14:58:47adminsetgithub: 74712
2017-05-31 19:49:55lazkasetmessages: + msg294867
2017-05-31 17:35:17skrahsetmessages: + msg294860
2017-05-31 17:32:00lazkasetstatus: open -> closed
resolution: not a bug
messages: + msg294858

stage: resolved
2017-05-31 17:23:54skrahsetmessages: + msg294856
2017-05-31 17:10:20lazkasetmessages: + msg294853
2017-05-31 17:05:01skrahsetnosy: + skrah
messages: + msg294852
2017-05-31 16:35:05lazkacreate