我正在使用嵌入式python解释器加载一些PySide(或PyQt4)脚本的C ++ Qt4应用程序。我注意到Address Sanitizer在退出c ++退出时报告了内存泄漏。
为了解决这个问题,我编写了一个嵌入在C ++中的简单PySide代码,试图了解内存泄漏的来源。
我在尝试各种各样的事情时花了很长时间,但无济于事。我怀疑它与某些引用计数错误有关,当Python解释器关闭时会造成一些麻烦,但我不确定。
有人可以帮我理解我做错了吗?
这是我的简单代码:
#include <iostream>
#include "Python.h"
class EmbedPySide
{
public:
EmbedPySide()
{
char name[] = "test";
Py_SetProgramName(name);
Py_Initialize();
std::string code =
"from PySide import QtGui\n"
""
"class EmbededPySide(QtGui.QApplication):\n"
""
" def __init__(self):\n"
" super(EmbededPySide, self).__init__([])\n"
" self.button = QtGui.QPushButton('Shutdown')\n"
" self.button.clicked.connect(self.cleanUp)\n"
" self.win = QtGui.QMainWindow()\n"
" self.win.setCentralWidget(self.button)\n"
" self.win.move(600, 300)\n"
" self.win.show()\n"
""
" def cleanUp(self):\n"
" del self.button\n"
" del self.win\n"
" self.quit()\n"
""
"if __name__=='__main__':\n"
" app = EmbededPySide()\n"
" app.exec_()";
PyRun_SimpleString(code.c_str());
}
~EmbedPySide()
{
Py_Finalize();
std::cout << "Destructor called" << std::endl;
}
};
int main()
{
EmbedPySide embedded;
std::cout << "Exiting" << std::endl;
}
我编译它:
g++ main.cpp -O1 -g -fsanitize=address -fno-omit-frame-pointer \
-I/usr/include/python2.7 -lpython2.7
为清楚起见,这是我在代码字符串中编写的python代码:
from PySide import QtGui
class EmbededPySide(QtGui.QApplication):
def __init__(self):
super(EmbededPySide, self).__init__([])
self.button = QtGui.QPushButton('Shutdown')
self.button.clicked.connect(self.cleanUp)
self.win = QtGui.QMainWindow()
self.win.setCentralWidget(self.button)
self.win.move(600, 300)
self.win.show()
def cleanUp(self):
del self.button
del self.win
self.quit()
if __name__=='__main__':
app = EmbededPySide()
app.exec_()
在运行中,这是我得到的输出:
退出
析构函数叫
=============================================== ================== == 5063 ==错误:LeakSanitizer:检测到内存泄漏
直接泄漏1277个对象中的3377664个字节,这些对象分配自: __interceptor_calloc中的#0 0x7f161d4fb79a(/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9879a) #1 0x7f161d0349ab(/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x1619ab)
从以下分配的1个对象直接泄漏786432个字节: __interceptor_calloc中的#0 0x7f161d4fb79a(/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9879a) #1 0x7f161d0349ab(/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x1619ab) #2 0x4f622d95dcb87ff()
从以下分配的27个对象中直接泄漏24680个字节: malloc中的#0 0x7f161d4fb602(/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602) _PyObject_GC_Malloc中的#1 0x7f161cfacd48(/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0xd9d48)
[...]
谢谢!