<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hello,</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
I struggle for some time now to close a memory leak using std::vector with SIP (first SIP v6.0.3 and now 6.1).</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b>The valgrind output:</b></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<pre style="background-color:#ffffff;color:#080808;font-family:'JetBrains Mono',monospace;font-size:9.8pt">==26606== 16 bytes in 1 blocks are definitely lost in loss record 6 of 4,537<br>==26606== at 0x4C3217F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)<br>==26606== by 0x6FB1542: allocate (new_allocator.h:111)<br>==26606== by 0x6FB1542: allocate (alloc_traits.h:436)<br>==26606== by 0x6FB1542: _M_allocate (stl_vector.h:172)<br>==26606== by 0x6FB1542: _M_allocate_and_copy<__gnu_cxx::__normal_iterator<ActionID* const*, std::vector<ActionID*> > > (stl_vector.h:1260)<br>==26606== by 0x6FB1542: std::vector<ActionID*, std::allocator<ActionID*> >::operator=(std::vector<ActionID*, std::allocator<ActionID*> > const&) (vector.tcc:206)<br>==26606== by 0x6FBE60C: varset_RoadWorksContainerExtended_referenceDenms (sipdenm_pduRoadWorksContainerExtended.cpp:347)<br>==26606== by 0x7CEF538: sipVariableDescr_descr_set (descriptors.c:415)<br>==26606== by 0x5CDD3F: _PyObject_GenericSetAttrWithDict (in /usr/bin/python3.8)<br>==26606== by 0x5D613F: PyObject_SetAttr (in /usr/bin/python3.8)<br>==26606== by 0x578DE9: _PyEval_EvalFrameDefault (in /usr/bin/python3.8)<br>==26606== by 0x5760EC: _PyEval_EvalCodeWithName (in /usr/bin/python3.8)<br>==26606== by 0x6025C6: _PyFunction_Vectorcall (in /usr/bin/python3.8)<br>==26606== by 0x578798: _PyEval_EvalFrameDefault (in /usr/bin/python3.8)<br>==26606== by 0x5760EC: _PyEval_EvalCodeWithName (in /usr/bin/python3.8)<br>==26606== by 0x66299D: ??? (in /usr/bin/python3.8)</pre>
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b>The wrapper snipped mentioned in valgrind -> (sipdenm_pduRoadWorksContainerExtended.cpp:347):</b><br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<pre style="background-color:#ffffff;color:#080808;font-family:'JetBrains Mono',monospace;font-size:9.8pt"><span style="color:#0033b3">extern </span><span style="color:#067d17">"C" </span>{<span style="color:#0033b3">static int </span><span style="color:#00627a">varset_RoadWorksContainerExtended_referenceDenms</span>(<span style="color:#0033b3">void </span>*, PyObject *, PyObject *);}<br><span style="color:#0033b3">static int </span><span style="color:#00627a">varset_RoadWorksContainerExtended_referenceDenms</span>(<span style="color:#0033b3">void </span>*sipSelf, PyObject *sipPy, PyObject *)<br>{<br> ::<span style="color:#371f80">ReferenceDenms</span>*<span style="color:#000000">sipVal</span>;<br> ::<span style="color:#008080">RoadWorksContainerExtended </span>*<span style="color:#000000">sipCpp </span>= <span style="color:#0033b3">reinterpret_cast</span>< ::<span style="color:#008080">RoadWorksContainerExtended </span>*>(sipSelf);<br><br> <span style="color:#0033b3">int </span><span style="color:#000000">sipIsErr </span>= <span style="color:#1750eb">0</span>;<br> <span style="color:#0033b3">int </span><span style="color:#000000">sipValState</span>;<br> sipVal = <span style="color:#0033b3">reinterpret_cast</span>< ::ReferenceDenms *>(sipForceConvertToType(sipPy, sipType_std_vector_0101ActionID, SIP_NULLPTR, SIP_NOT_NONE, &sipValState, &sipIsErr));<br><br> <span style="color:#0033b3">if </span>(<span style="color:#000000">sipIsErr</span>)<br> <span style="color:#0033b3">return </span>-<span style="color:#1750eb">1</span>;<br><br> <span style="color:#000000">sipCpp</span>-><span style="color:#660e7a">referenceDenms </span><span style="color:#008080">= </span>*<span style="color:#000000">sipVal</span>; <- 347<br><br> sipReleaseType(sipVal, sipType_std_vector_0101ActionID, sipValState);<br><br> <span style="color:#0033b3">return </span><span style="color:#1750eb">0</span>;<br>}</pre>
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b><br>
</b></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b>The python code:</b></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<pre style="background-color:#ffffff;color:#080808;font-family:'JetBrains Mono',monospace;font-size:9.8pt">actionId1 = denm_pdu.ActionID()<br>actionId1.originatingStationID = <span style="color:#1750eb">4294902015<br></span>actionId1.sequenceNumber = <span style="color:#1750eb">12<br></span>actionId2 = denm_pdu.ActionID()<br>actionId2.originatingStationID = <span style="color:#1750eb">4294902016<br></span>actionId2.sequenceNumber = <span style="color:#1750eb">13<br></span>roadWorksContainerExtended.referenceDenms = [actionId1, actionId2]</pre>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b>The sip-file:</b></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<pre style="background-color:#ffffff;color:#080808;font-family:'JetBrains Mono',monospace;font-size:9.8pt"><span style="color:#0033b3">...<br><br>typedef </span>std::vector<ActionID*> <span style="color:#371f80">ReferenceDenms</span>;<br><br>...<br><br><pre style="background-color:#ffffff;color:#080808;font-family:'JetBrains Mono',monospace;font-size:9.8pt"><span style="color:#0033b3">struct </span><span style="color:#008080">RoadWorksContainerExtended </span>{<br><br>%TypeHeaderCode<br><span style="color:#9e880d">#include </span><span style="color:#067d17"><denm-desc.h><br></span>%End<br><br> <span style="color:#371f80">ReferenceDenms </span><span style="color:#660e7a">referenceDenms</span>;<br> <span style="color:#00627a">RoadWorksContainerExtended </span>();<br>} ;</pre><br></pre>
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b>The MappedType:</b></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="color:#8c8c8c;font-style:italic"></span><br>
<span style="color:#8c8c8c;font-style:italic"></span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<pre style="background-color:#ffffff;color:#080808;font-family:'JetBrains Mono',monospace;font-size:9.8pt"><span style="color:#0033b3">template</span><TYPE><br>%MappedType std::vector<TYPE *><br>{<br>%TypeHeaderCode<br><span style="color:#9e880d">#include </span><span style="color:#067d17"><vector><br></span><span style="color:#9e880d">#include </span><span style="color:#067d17"><iostream><br></span>%End<br><br><span style="color:#8c8c8c;font-style:italic">// from python<br></span>%ConvertToTypeCode<br> <span style="color:#0033b3">const </span>sipTypeDef* kpTypeDef = sipFindType(<span style="color:#067d17">"TYPE"</span>);<br><br> <span style="color:#0033b3">if </span>(!kpTypeDef) {<br> std::cout << <span style="color:#067d17">"Error in vector_ptr.sip - ConvertToTypeCode: "<br></span><span style="color:#067d17"> "Could not find a matching type for 'TYPE'</span><span style="color:#0037a6">\n</span><span style="color:#067d17">"</span>;<br> <span style="color:#0033b3">return </span><span style="color:#1750eb">0</span>;<br> }<br><br> <span style="color:#8c8c8c;font-style:italic">// See if we are just being asked to check the type of the Python object.<br></span><span style="color:#8c8c8c;font-style:italic"> </span><span style="color:#0033b3">if </span>(sipIsErr == NULL) {<br> <span style="color:#8c8c8c;font-style:italic">// Check it is a list.<br></span><span style="color:#8c8c8c;font-style:italic"> </span><span style="color:#0033b3">if </span>(!PyList_Check(sipPy)) {<br> <span style="color:#0033b3">return </span><span style="color:#1750eb">0</span>;<br> }<br><br> <span style="color:#8c8c8c;font-style:italic">// Now check each element of the list is of the type we expect.<br></span><span style="color:#8c8c8c;font-style:italic"> // The template is for a pointer type so we don't disallow None.<br></span><span style="color:#8c8c8c;font-style:italic"> </span><span style="color:#0033b3">for </span>(Py_ssize_t i = <span style="color:#1750eb">0</span>; i < PyList_GET_SIZE(sipPy); ++i) {<br><br> PyObject *item = PyList_GET_ITEM(sipPy, i);<br><br> <span style="color:#0033b3">if </span>(!sipCanConvertToType(item, kpTypeDef, SIP_NOT_NONE)) {<br> std::cout << <span style="color:#067d17">"Error in vector_ptr.sip - ConvertToTypeCode: "<br></span><span style="color:#067d17"> "Object cannot be converted to TYPE'</span><span style="color:#0037a6">\n</span><span style="color:#067d17">"</span>;<br> <span style="color:#0033b3">return </span><span style="color:#1750eb">0</span>;<br> }<br> }<br> <span style="color:#0033b3">return </span><span style="color:#1750eb">1</span>;<br> }<br><br> Py_ssize_t len = PyList_GET_SIZE(sipPy);<br> <span style="color:#8c8c8c;font-style:italic">// Create the instance on the heap.<br></span><span style="color:#8c8c8c;font-style:italic"> </span>std::vector<TYPE *> *v = <span style="color:#0033b3">new </span>std::vector<TYPE *>;<br> v->reserve(len);<br><br> <span style="color:#0033b3">for </span>(Py_ssize_t i = <span style="color:#1750eb">0</span>; i < len; ++i) {<br><br> <span style="color:#0033b3">int </span>state;<br> <span style="color:#8c8c8c;font-style:italic">// Use the SIP API to convert the Python object to the corresponding C++ instance. Note that we apply any<br></span><span style="color:#8c8c8c;font-style:italic"> // ownership transfer to the list itself, not the individual elements.<br></span><span style="color:#8c8c8c;font-style:italic"> </span>TYPE *t = <span style="color:#0033b3">static_cast</span><TYPE *>(sipConvertToType(PyList_GET_ITEM(sipPy, i), kpTypeDef, NULL, SIP_NOT_NONE, &state, sipIsErr));<br><br> <span style="color:#8c8c8c;font-style:italic">// Deal with any errors<br></span><span style="color:#8c8c8c;font-style:italic"> </span><span style="color:#0033b3">if </span>(*sipIsErr) {<br> std::cout << <span style="color:#067d17">"Error in vector_ptr.sip - ConvertToTypeCode: "<br></span><span style="color:#067d17"> "Error occurred - cleanup on the heap ...'</span><span style="color:#0037a6">\n</span><span style="color:#067d17">"</span>;<br> <span style="color:#8c8c8c;font-style:italic">// Tidy up.<br></span><span style="color:#8c8c8c;font-style:italic"> </span>sipReleaseType(t, kpTypeDef, state);<br> <span style="color:#0033b3">delete </span>v;<br><br> <span style="color:#8c8c8c;font-style:italic">// There is nothing on the heap.<br></span><span style="color:#8c8c8c;font-style:italic"> </span><span style="color:#0033b3">return </span><span style="color:#1750eb">0</span>;<br> }<br><br> <span style="color:#8c8c8c;font-style:italic">// Add the pointer to the C++ instance.<br></span><span style="color:#8c8c8c;font-style:italic"> </span>v->push_back(t);<br> }<br><br> <span style="color:#8c8c8c;font-style:italic">// Return the instance on the heap.<br></span><span style="color:#8c8c8c;font-style:italic"> </span>*sipCppPtr = v;<br><br> <span style="color:#8c8c8c;font-style:italic">// Apply the normal transfer.<br></span><span style="color:#8c8c8c;font-style:italic"> </span><span style="color:#0033b3">return </span>sipGetState(sipTransferObj);<br>%End<br><br><span style="color:#8c8c8c;font-style:italic">// from c++<br></span>%ConvertFromTypeCode<br> PyObject *l;<br><br> <span style="color:#0033b3">const </span>sipTypeDef* kpTypeDef = sipFindType(<span style="color:#067d17">"TYPE"</span>);<br><br> <span style="color:#0033b3">if </span>(!kpTypeDef) {<br> std::cout << <span style="color:#067d17">"Error in vector_ptr.sip - ConvertFromTypeCode: "<br></span><span style="color:#067d17"> "Could not find a matching type for 'TYPE'</span><span style="color:#0037a6">\n</span><span style="color:#067d17">"</span>;<br> <span style="color:#0033b3">return </span>NULL;<br> }<br><br> <span style="color:#8c8c8c;font-style:italic">// Create the Python list of the correct length.<br></span><span style="color:#8c8c8c;font-style:italic"> </span><span style="color:#0033b3">if </span>((l = PyList_New(sipCpp->size())) == NULL) {<br> std::cout << <span style="color:#067d17">"Error in vector_ptr.sip - ConvertFromTypeCode: "<br></span><span style="color:#067d17"> "Could not create python list'</span><span style="color:#0037a6">\n</span><span style="color:#067d17">"</span>;<br> <span style="color:#0033b3">return </span>NULL;<br> }<br><br> <span style="color:#0033b3">int </span>i = <span style="color:#1750eb">0</span>;<br> <span style="color:#8c8c8c;font-style:italic">// Go through each element in the C++ instance and convert it to the corresponding Python object.<br></span><span style="color:#8c8c8c;font-style:italic"> </span><span style="color:#0033b3">for</span>(std::vector<TYPE *>::iterator iter = sipCpp->begin(); iter != sipCpp->end(); ++iter) {<br> TYPE *t = *iter;<br> PyObject *tobj;<br><br> <span style="color:#0033b3">if </span>((tobj = sipConvertFromType(t, kpTypeDef, sipTransferObj)) == NULL) {<br><br> <span style="color:#8c8c8c;font-style:italic">// There was an error so garbage collect the Python list.<br></span><span style="color:#8c8c8c;font-style:italic"> </span>Py_XDECREF(tobj);<br> Py_XDECREF(l);<br> std::cout << <span style="color:#067d17">"Error in vector_ptr.sip - ConvertFromTypeCode: "<br></span><span style="color:#067d17"> "Could not convert type in Python list'</span><span style="color:#0037a6">\n</span><span style="color:#067d17">"</span>;<br> <span style="color:#0033b3">return </span>NULL;<br> }<br><br> PyList_SET_ITEM(l, i++, tobj);<br> }<br><br> <span style="color:#8c8c8c;font-style:italic">// Return the Python list.<br></span><span style="color:#8c8c8c;font-style:italic"> </span><span style="color:#0033b3">return </span>l;<br>%End<br>};</pre>
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
I tried changing the ownership to c++ of every item when creating vector in the MappedType - ConvertToTypeCode but no effect.</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Running sip-install with tracing or debug option gives no further information.<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Does someone have an idea how this leak could be closed or what else one could try to close it?</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Any help would be appreciated.</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Thank you!<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
M.T.<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
</body>
</html>