0

I am trying to copy data from one container type to another container type, the containers are both double dimensional vectors, i am using boost::combine and boost::tie to iterate over the containers, the code builds fine but throws a bad_alloc when run. i am not able to understand why a simple code like below throw bad_alloc, what am i doing wrong ?? also what are the other strategies to copy data between containers when they are multi-dimensional.

#include <vector>
#include <iostream>
#include <boost/foreach.hpp>
#include <boost/container/small_vector.hpp>
#include <boost/range/combine.hpp>
#include <algorithm>
#include <tuple>

int
main(int ac, char **av)
{
    std::vector<std::vector<int>> bv(1, std::vector<int>(4, 99));
    boost::container::small_vector<boost::container::small_vector<int, 4>, 1> bvv;
    decltype(bv)::value_type v1;
    decltype(bvv)::value_type v2;
    BOOST_FOREACH(boost::tie(v1, v2), boost::combine(bv, bvv)){
        for ( auto &e : v1 )
            v2.push_back( e );
    }
    return 0;
}
Ravikumar Tulugu
  • 1,702
  • 2
  • 18
  • 40

1 Answers1

1

boost::combine expects the passed arguments have the same size. In your case bv has 1 vector<int> but bvv has 0 elements of boost::container::small_vector type. And for this reason program crashed. You can add 1 to constructor of small_vector

boost::container::small_vector<boost::container::small_vector<int, 4>, 1> bvv(1);

then program works, but it doesn't do what you expected. v2 vector is created as new local variable in main function and it is filled by elements of first vector from bv container. I think you want to fill bvv vector by elements from bv container.

If you want to modify bvv vector you should pass it as parameter to boost::tie function.

    BOOST_FOREACH(boost::tie(bv[0], bvv[0]), boost::combine(bv, bvv)){
       std::copy (bv[0].begin(), bv[0].end(), std::back_inserter(bvv[0]));
    }

but it only works if bvv and bv have one element.

Maybe you should not use boost::combine and just write loop to iterate over all elements in bv and add them to bvv container.

    for (const auto& v : bv)
    {
        bvv.push_back(boost::container::small_vector<int, 4>());
        std::copy (v.begin(), v.end(), std::back_inserter(bvv.back()));
    }
rafix07
  • 20,001
  • 3
  • 20
  • 33
  • But i was using boost::small_vector which is supposed to preallocate and pre-reserve the size ??? – Ravikumar Tulugu Mar 15 '18 at 08:42
  • `small_vector` N means preallocated elements, but without calling `push_back`, `resize` etc method it still has 0 elements. `N` is used to allocate memory for elements then while using `push_back` may be faster, but you need to add element explicitly way. – rafix07 Mar 15 '18 at 08:49