Using boost :: python :: list as return value need to increase ob_refcnt?

I try my best to find memory leaks in a very important module in our project and get a code snippet as follows:

PyObject* python_func( const char* str ) { .......................... boost::python::list obj; obj.append(str); obj.ptr()->ob_refcnt++; //this is necessary?? return obj.ptr(); } 

I got confused on this line: obj.ptr()->ob_refcnt++;

I think that ob_refcnt is supported by python inside gc, we cannot use it, so obviously this will lead to a memory leak, on the other hand, obj is going to leave its scope, I am not sure that boost :: python :: list deconstructor will reduce ob_refcnt, if true, delete this line, the obj hold resource will be released, which will lead to failure.

So my question is: is obj.ptr()->ob_refcnt++; and why?

+4
source share
1 answer

The reason that the code increases the number of links is because python_func designed to return a new link to an object. (A new link is one in which the reference count has already been increased - returning a new link allows the function to create new objects, such as a new list in this case.) On the other hand, the ptr() member function returns a borrowed reference to the object.

As you correctly understood, if the code could not increase the reference counter of the borrowed link, the boost::python::list destructor would decrease the reference counter, and the returned object would be invalid.

Note that you should never directly access the ob_refcnt PyObject element. The proper way to increase the reference count is to use the Py_INCREF macro or its equivalent boost::python boost::python::incref :

 return boost::python::incref(obj.ptr()); 
+2
source

Source: https://habr.com/ru/post/1496375/


All Articles