Boost C++ Libraries: Ticket #11369: Boost.Python: return_internal_reference<> bug https://svn.boost.org/trac10/ticket/11369 <p> I am having an issue with Boost.Python with a very simple use case. </p> <p> I am returning a reference to an object, and it seems that my python object looses its C++ object's reference at a stage for some reason. </p> <p> Please see my example below reproducing this issue. </p> <p> C++ Code: </p> <pre class="wiki">#include &lt;vector&gt; #include &lt;string&gt; #include &lt;cmath&gt; #include &lt;boost/python.hpp&gt; #include &lt;boost/python/suite/indexing/vector_indexing_suite.hpp&gt; class Car { public: Car(std::string name) : m_name(name) {} bool operator==(const Car &amp;other) const { return m_name == other.m_name; } std::string GetName() { return m_name; } private: std::string m_name; }; class Factory { public: Factory(std::string name) : m_name(name) {} bool operator==(const Factory &amp;other) const { return m_name == other.m_name &amp;&amp; m_car_list == other.m_car_list; } Car&amp; create_car(std::string name) { m_car_list.emplace_back(Car(name)); return m_car_list.back(); } std::string GetName() { return m_name; } std::vector&lt;Car&gt;&amp; GetCarList() { return m_car_list;} private: std::string m_name; std::vector&lt;Car&gt; m_car_list; }; class Manufacturer { public: Manufacturer(std::string name) : m_name(name) {} bool operator==(const Manufacturer &amp;other) const { return m_name == other.m_name &amp;&amp; m_factory_list == other.m_factory_list; } Factory&amp; create_factory(std::string name) { m_factory_list.emplace_back(Factory(name)); return m_factory_list.back(); } std::string GetName() { return m_name; } std::vector&lt;Factory&gt;&amp; GetFactoryList() { return m_factory_list;} private: std::string m_name; std::vector&lt;Factory&gt; m_factory_list; }; BOOST_PYTHON_MODULE(carManufacturer) { using namespace boost::python; class_&lt;Manufacturer&gt;("Manufacturer", init&lt;std::string&gt;()) .add_property("factory_list", make_function(&amp;Manufacturer::GetFactoryList, return_internal_reference&lt;&gt;())) .add_property("name", &amp;Manufacturer::GetName) .def("create_factory", &amp;Manufacturer::create_factory, return_internal_reference&lt;&gt;()); class_&lt;Factory&gt;("Factory", init&lt;std::string&gt;()) .add_property("car_list", make_function(&amp;Factory::GetCarList, return_internal_reference&lt;&gt;())) .add_property("name", &amp;Factory::GetName) .def("create_car", &amp;Factory::create_car, return_internal_reference&lt;&gt;()); class_&lt;Car&gt;("Car", init&lt;std::string&gt;()) .add_property("name", &amp;Car::GetName); class_&lt;std::vector&lt;Factory&gt; &gt;("FactoryList") .def(vector_indexing_suite&lt;std::vector&lt;Factory&gt; &gt;()); class_&lt;std::vector&lt;Car&gt; &gt;("Car") .def(vector_indexing_suite&lt;std::vector&lt;Car&gt; &gt;()); } </pre><p> Python Code: </p> <pre class="wiki">from carManufacturer import * vw = Manufacturer("VW") vw_bra_factory = vw.create_factory("Brazil Factory") beetle = vw_bra_factory.create_car("Beetle69") if vw_bra_factory is vw.factory_list[0]: print("equal.") else: print("NOT EQUAL") print("## I expected them to be the same reference..?") print("vw_bra_factory Car List size : " + str(len(vw_bra_factory.car_list))) print("Actual Car List size : " + str(len(vw.factory_list[0].car_list))) print("## This still works. Maybe the python objects differ, but refer to the same C++ object. I can live with that.") vw_sa_factory = vw.create_factory("South Africa Factory") print("vw_bra_factory Car List size : " + str(len(vw_bra_factory.car_list))) print("Actual Car List size : " + str(len(vw.factory_list[0].car_list))) print("## .. what? why? brazil py object has no cars now? I don't get it. I can't have any of that.") print("## What will happen if I create another car in the brazil factory?") combi = vw_bra_factory.create_car("Hippie van") print("vw_bra_factory Car List size : " + str(len(vw_bra_factory.car_list))) print("Actual Car List size : " + str(len(vw.factory_list[0].car_list))) print("## And another.") citi_golf = vw_bra_factory.create_car("Citi golf") print("vw_bra_factory Car List size : " + str(len(vw_bra_factory.car_list))) print("Actual Car List size : " + str(len(vw.factory_list[0].car_list))) print("## 'vw_bra_factory' must have lost its C++ reference it had to 'vw.factory_list[0]' when I created a new factory. Why?") </pre><p> Output: </p> <pre class="wiki">NOT EQUAL ## I expected them to be the same reference..? vw_bra_factory Car List size : 1 Actual Car List size : 1 ## This still works. Maybe the python objects differ, but refer to the same C++ object. I can live with that. vw_bra_factory Car List size : 0 Actual Car List size : 1 ## .. what? why? brazil py object has no cars now? I don't get it. I can't have any of that. ## What will happen if I create another car in the brazil factory? vw_bra_factory Car List size : 1 Actual Car List size : 1 ## And another. vw_bra_factory Car List size : 2 Actual Car List size : 1 ## 'vw_bra_factory' must have lost its C++ reference it had to 'vw.factory_list[0]' when I created a new factory. Why? </pre><p> This is just an example made to reproduce my real work's problem in a presentable way. </p> <p> Is there any workaround to this? I could not find any in bug reports, the mailing list or anywhere else. </p> <p> Regards, Christoff </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11369 Trac 1.4.3 anonymous Wed, 03 Jun 2015 08:41:48 GMT <link>https://svn.boost.org/trac10/ticket/11369#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11369#comment:1</guid> <description> <p> <strong>Workarounds:</strong> </p> <p> Thanks to someone on the mailing list for figuring out what the problem is: </p> <p> It works when I reserve the vectors sizes to e.g. 32. (Not that it fixes the bug, it only deters the bug to occur until the reserve size is exceeded.) </p> <p> It also works if I allocate the objects stored in the vectors on the heap. </p> </description> <category>Ticket</category> </item> </channel> </rss>