I was thinking of revisiting cpp_dec_float for that reason too - thanks for noting that. Here's the result with address sanitizer ...
=================================================================
==15679==ERROR: AddressSanitizer: heap-use-after-free on address 0x60600000ea48 at pc 0x0000004228c3 bp 0x7f2e041f16a0 sp 0x7f2e041f1698
READ of size 40 at 0x60600000ea48 thread T0
#0 0x4228c2 in boost::multiprecision::backends::cpp_dec_float<50u, int, void>::cpp_dec_float(boost::multiprecision::backends::cpp_dec_float<50u, int, void> const&) /usr/include/boost/multiprecision/cpp_dec_float.hpp:210
#1 0x427592 in boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<50u, int, void>, (boost::multiprecision::expression_template_option)1>::number(boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<50u, int, void>, (boost::multiprecision::expression_template_option)1> const&) /usr/include/boost/multiprecision/number.hpp:47
#2 0x4168ae in transform<__gnu_cxx::__normal_iterator<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<50> >*, std::vector<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<50> > > >, std::back_insert_iterator<std::vector<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<50> > > >, higher_high::calculate(const positions_map&, const last_tick&)::<lambda(boost::multiprecision::cpp_dec_float_50)> > /usr/include/c++/11/bits/stl_algo.h:4296
#3 0x410ca3 in higher_high::calculate(std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, trade_position, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, trade_position> > > const&, last_tick const&) ../src/higher_high.cpp:197
#4 0x4aca5d in operator() ../src/ib_trading_engine.cpp:228
#5 0x4c11d1 in operator() /usr/include/boost/coroutine2/detail/push_control_block_cc.ipp:90
#6 0x4c27e5 in __invoke_impl<boost::context::fiber, boost::coroutines2::detail::push_coroutine<last_tick>::control_block::control_block<boost::context::basic_fixedsize_stack<boost::context::stack_traits>, ib_trading_engine::run()::<lambda(boost::coroutines2::coroutine<last_tick>::pull_type&)> >(boost::context::preallocated, boost::context::basic_fixedsize_stack<boost::context::stack_traits>&&, ib_trading_engine::run()::<lambda(boost::coroutines2::coroutine<last_tick>::pull_type&)>&&)::<lambda(boost::context::fiber&&)>&, boost::context::fiber> /usr/include/c++/11/bits/invoke.h:61
#7 0x4c25d0 in __invoke<boost::coroutines2::detail::push_coroutine<last_tick>::control_block::control_block<boost::context::basic_fixedsize_stack<boost::context::stack_traits>, ib_trading_engine::run()::<lambda(boost::coroutines2::coroutine<last_tick>::pull_type&)> >(boost::context::preallocated, boost::context::basic_fixedsize_stack<boost::context::stack_traits>&&, ib_trading_engine::run()::<lambda(boost::coroutines2::coroutine<last_tick>::pull_type&)>&&)::<lambda(boost::context::fiber&&)>&, boost::context::fiber> /usr/include/c++/11/bits/invoke.h:97
#8 0x4c2537 in invoke<boost::coroutines2::detail::push_coroutine<last_tick>::control_block::control_block<boost::context::basic_fixedsize_stack<boost::context::stack_traits>, ib_trading_engine::run()::<lambda(boost::coroutines2::coroutine<last_tick>::pull_type&)> >(boost::context::preallocated, boost::context::basic_fixedsize_stack<boost::context::stack_traits>&&, ib_trading_engine::run()::<lambda(boost::coroutines2::coroutine<last_tick>::pull_type&)>&&)::<lambda(boost::context::fiber&&)>&, boost::context::fiber> /usr/include/c++/11/functional:98
#9 0x4c2297 in run /usr/include/boost/context/fiber_fcontext.hpp:140
#10 0x4c2043 in fiber_entry<boost::context::detail::fiber_record<boost::context::fiber, boost::context::basic_fixedsize_stack<boost::context::stack_traits>, boost::coroutines2::detail::push_coroutine<last_tick>::control_block::control_block<boost::context::basic_fixedsize_stack<boost::context::stack_traits>, ib_trading_engine::run()::<lambda(boost::coroutines2::coroutine<last_tick>::pull_type&)> >(boost::context::preallocated, boost::context::basic_fixedsize_stack<boost::context::stack_traits>&&, ib_trading_engine::run()::<lambda(boost::coroutines2::coroutine<last_tick>::pull_type&)>&&)::<lambda(boost::context::fiber&&)> > > /usr/include/boost/context/fiber_fcontext.hpp:80
#11 0x7f2e0740118e in make_fcontext (/lib64/libboost_context.so.1.78.0+0x118e)
0x60600000ea58 is located 0 bytes to the right of 56-byte region [0x60600000ea20,0x60600000ea58)
freed by thread T0 here:
#0 0x7f2e074b8dc7 in operator delete(void*, unsigned long) (/lib64/libasan.so.6+0xb3dc7)
previously allocated by thread T0 here:
#0 0x7f2e074b7f47 in operator new(unsigned long) (/lib64/libasan.so.6+0xb2f47)
SUMMARY: AddressSanitizer: heap-use-after-free /usr/include/boost/multiprecision/cpp_dec_float.hpp:210 in boost::multiprecision::backends::cpp_dec_float<50u, int, void>::cpp_dec_float(boost::multiprecision::backends::cpp_dec_float<50u, int, void> const&)
Shadow bytes around the buggy address:
0x0c0c7fff9cf0: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
0x0c0c7fff9d00: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
0x0c0c7fff9d10: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
0x0c0c7fff9d20: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
0x0c0c7fff9d30: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
=>0x0c0c7fff9d40: fa fa fa fa fd fd fd fd fd[fd]fd fa fa fa fa fa
0x0c0c7fff9d50: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
0x0c0c7fff9d60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0c7fff9d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0c7fff9d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0c7fff9d90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==15679==ABORTING