Ich versuche nur zu verstehen, wie man mit den Referenzzählungen umgehen muss, wenn man die Python C API benutzt.Python C API, hohe Anzahl von Referenzen für neues Objekt
Ich möchte eine Python-Funktion in C++ nennen, wie folgt aus:
PyObject* script;
PyObject* scriptRun;
PyObject* scriptResult;
// import module
script = PyImport_ImportModule("pythonScript");
// get function objects
scriptRun = PyObject_GetAttrString(script, "run");
// call function without/empty arguments
scriptResult = PyObject_CallFunctionObjArgs(scriptRun, NULL);
if (scriptResult == NULL)
cout << "scriptResult = null" << endl;
else
cout << "scriptResult != null" << endl;
cout << "print reference count: " << scriptResult->ob_refcnt << endl;
Der Python-Code in pythonScript.py ist sehr einfach:
def run():
return 1
Die Dokumentation "PyObject_CallFunctionObjArgs" sagt, Sie erhalten eine neue Referenz als Rückgabewert. So würde ich „Script“ erwartet einen Referenzzähler von 1 zu haben, aber der Ausgang ist:
scriptResult != null
print reference count: 72
Außerdem würde ich einen Speicherverlust erwarten, wenn ich dies in einer Schleife tun würde, ohne den Referenzzähler abnimmt. Dies scheint jedoch nicht zu geschehen.
Könnte jemand mir helfen zu verstehen?
Mit freundlichen Grüßen!
Eine weitere Frage: Dank @ecatmur und @KayZhu verstehe ich jetzt, warum es kein Speicherleck gibt. Trotzdem, wenn ich diesen Code in einer langen Schleife laufen lasse, zerquetscht mein vollständiges Betriebssystem sowieso. Die Referenzzählung auf "1" nimmt mit jeder Iteration zu, aber ich sehe nicht, warum dies zu einem Systemfehler führen sollte. – user1774143
Schleifen Sie, bis "ob_refcnt" durch 0 zurückläuft? Die Referenzzahl von 1 schwankt stark. Wenn Sie nach 0 fortfahren, könnten normale Operationen 'Py_DECREF' auf 0 setzen und dazu führen, dass 'int'1 freigegeben wird, gefolgt von einem segfault. Versuchen Sie es mit einem weniger häufig internierten "Int" wie 13. – eryksun
Zumindest war ich nicht bis "sys.maxint" (das ist "9223372036854775807" auf meinem System). Heute scheint es, dass ich den Fehler nicht reproduzieren kann und ich denke, ich sollte aufhören, meinen Arbeitstisch zu erschießen. Danke für Ihre Hilfe! – user1774143