Boost logo

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