Boost C++ Libraries: Ticket #11000: Rogue fibonacci_heap constructor corrupts source https://svn.boost.org/trac10/ticket/11000 <p> As analyzed on stackoverflow (<a class="ext-link" href="http://stackoverflow.com/a/28384938/85371"><span class="icon">​</span>http://stackoverflow.com/a/28384938/85371</a>) copying from a non-const lvalue fibonacci_heap corrupts the source heap. </p> <p> It splices the roots from the source intrusive-list. </p> <p> In fact the particular constructor overload seems redundant. The documentation lists it as the 4th overload (<a href="http://www.boost.org/doc/libs/1_57_0/doc/html/boost/heap/fibonacci_heap.html#idp107311392-bb">http://www.boost.org/doc/libs/1_57_0/doc/html/boost/heap/fibonacci_heap.html#idp107311392-bb</a>), but doesn't specify what the behaviour should be. </p> <p> In practice the behaviour is equivalent to (partial) move-construction, which obviously is not what the caller is expecting. </p> <p> Removing the "rogue" constructor removes symptoms. </p> <p> Reproducer: live on <a class="ext-link" href="http://coliru.stacked-crooked.com/a/8f58113aaef53ef5"><span class="icon">​</span>http://coliru.stacked-crooked.com/a/8f58113aaef53ef5</a> </p> <pre class="wiki">#include &lt;boost/heap/fibonacci_heap.hpp&gt; #include &lt;iostream&gt; #include &lt;random&gt; namespace { std::discrete_distribution&lt;int&gt; dist({1,1,1,1,1,1}); static auto price_gen = [&amp;] { static std::mt19937 rng; static double values[] = {52.40, 12.30, 87.10, 388., 0.10, 23.40}; return values[dist(rng)]; }; } struct Order { double price = price_gen(); unsigned quantity = rand() % 4 + 1; double subtotal() const { return price * quantity; } bool operator&lt;(Order const&amp; other) const { return subtotal() &lt; other.subtotal(); } }; using Heap = boost::heap::fibonacci_heap&lt;Order&gt;; struct Y { virtual void printSnapshot(std::ostream &amp;ss) { //Heap cloned(static_cast&lt;Heap const&amp;&gt;(this-&gt;heap)); Heap cloned(this-&gt;heap); // CORRUPTS THE SOURCE HEAP double prev_price = std::numeric_limits&lt;double&gt;::max(); while (cloned.size() &gt; 0) { const Order &amp;order = cloned.top(); if (order.price != prev_price) { if (prev_price != std::numeric_limits&lt;double&gt;::max()) ss &lt;&lt; std::endl; ss &lt;&lt; order.price &lt;&lt; " | "; } ss &lt;&lt; order.quantity &lt;&lt; " "; prev_price = order.price; cloned.pop(); } ss &lt;&lt; std::endl; } void generateOrders() { for (int i=0; i&lt;3; ++i) { heap.push({}); } } Heap heap; }; int main() { Y y; for(int i=0; i&lt;10; ++i) { y.generateOrders(); y.printSnapshot(std::cout); } } </pre><pre class="wiki">52.4 | 4 23.4 | 3 2 388 | 4 Segmentation fault (core dumped) </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11000 Trac 1.4.3 timblechmann Sun, 08 Feb 2015 04:40:55 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/11000#comment:1 https://svn.boost.org/trac10/ticket/11000#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> thanks for reporting and analysing! </p> <p> fixed in git/develop! </p> Ticket