|
Boost : |
From: Tanguy Fautre (tanguy.fautre_at_[hidden])
Date: 2006-07-03 06:51:29
Hi,
I've been assessing and learning boost.python (1.33.1). But when I add
memory leak detection to a small test program (cf. attachment), I found
tons of memory leaks (about 20 leaks).
Even when the core of the program is only:
try {
Py_Initialize();
object main_module = object(
handle<>(borrowed(PyImport_AddModule("__main__"))) );
}
catch (const error_already_set &)
{
PyErr_Print();
}
Py_Finalize();
it is still finding some memory leaks.
Am I doing something wrong? Or is this a bug in boost.python?
Tanguy
#include <iostream>
#include <stdexcept>
#include <string>
#include <boost/python.hpp>
#if defined WIN32
#include <crtdbg.h>
#endif
using namespace boost::python;
class telemetry
{
public:
telemetry()
: m_Size(666), m_Name("telemetry name") { }
int size() const { return m_Size; }
std::string name() const { return m_Name; }
void resize(int s) { m_Size = s; }
void rename(const std::string & n) { m_Name = n; }
private:
int m_Size;
std::string m_Name;
};
const char * const Script =
"def test_function(): \n"
" print 'Python - test_function called correctly' \n"
"TM = telemetry() \n"
"print 'Python - TM size: ', TM.size() \n"
"print 'Python - TM name: ', TM.name() \n"
"print 'Python - changing TM size/name to 256/plop' \n"
"TM.resize(256) \n"
"TM.rename('plop') \n"
"print 'Python - TM size: ', TM.size() \n"
"print 'Python - TM name: ', TM.name() \n"
"print 'Python - SystemTM size: ', SystemTM.size() \n"
"print 'Python - SystemTM name: ', SystemTM.name() \n"
"print 'Python - changing SystemTM size/name to 256/plop' \n"
"SystemTM.resize(256) \n"
"SystemTM.rename('plop') \n"
"print 'Python - SystemTM size: ', SystemTM.size() \n"
"print 'Python - SystemTM name: ', SystemTM.name() \n"
;
int main(int argc, char * argv[])
{
#if defined WIN32 && ! defined NDEBUG
#pragma message("NOTE: Advanced Memory Leak Checks Enabled!")
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); // Get current flag
flag |= _CRTDBG_LEAK_CHECK_DF; // Turn on leak-checking bit
flag |= _CRTDBG_CHECK_ALWAYS_DF; // Turn on CrtCheckMemory
_CrtSetDbgFlag(flag); // Set flag to the new value
//_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_WNDW); // Pop-up an alert window (Otherwise alert are done on the debug output)
//_CrtSetBreakAlloc(1);
#endif
telemetry SystemTM;
try
{
std::cout << "C++ - SystemTM size: " << SystemTM.size() << std::endl;
std::cout << "C++ - SystemTM name: " << SystemTM.name() << std::endl;
Py_Initialize();
object main_module = object( handle<>(borrowed(PyImport_AddModule("__main__"))) );
object main_namespace = main_module.attr("__dict__");
object local_namespace = object(handle<>(PyDict_New()));
main_namespace["telemetry"] = class_<telemetry>("telemetry")
.def("size", &telemetry::size)
.def("name", &telemetry::name)
.def("resize", &telemetry::resize)
.def("rename", &telemetry::rename);
main_namespace["SystemTM"] = ptr(&SystemTM);
// compile the python script, but do not execute it
object compiled_code(
handle<>(
Py_CompileString(
Script,
"main.cpp.py",
Py_file_input
)
)
);
// execute the pre-compiled python script
{ handle<> ignore(
PyEval_EvalCode(
(PyCodeObject *) compiled_code.ptr(),
main_namespace.ptr(),
local_namespace.ptr()
)
); }
// execute a specific inline script on the local store of previous script
{ handle<> ignore(
PyRun_String(
"print 'Python - Local Namespace: TM.name() =', TM.name() \n"
"test_function() \n",
Py_file_input,
main_namespace.ptr(),
local_namespace.ptr()
)
); }
// memory leak test
//for (;;)
// handle<> ignore(PyRun_String("", Py_file_input, main_namespace.ptr(), local_namespace.ptr()));
std::cout << "C++ - SystemTM size: " << SystemTM.size() << std::endl;
std::cout << "C++ - SystemTM name: " << SystemTM.name() << std::endl;
}
catch (const error_already_set &)
{
PyErr_Print();
}
catch (const std::exception & Error)
{
std::cerr << "ERROR: " << Error.what() << std::endl;
}
Py_Finalize();
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk