boost::iterator_rangeを使用すると、無効な読み取り/セグメンテーション違反エラーが発生します。データはどこで範囲外になり、どうすればそれを防ぐことができますか?
問題を再現するためのコードを次に示します。
#include <iostream>
#include <vector>
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/range.hpp>
#include <boost/range/iterator_range.hpp>
これらは私のタイプです:
typedef double Value;
typedef std::vector<Value> vValue;
typedef boost::iterator_range<std::vector<Value>::iterator> rValue;
効用関数:
void print_range(const rValue &r) {
    for(rValue::difference_type i = 0; i < r.size(); ++i) std::cout << r[i] << " ";
    std::cout << std::endl;
}
これは、すべてのデータのキャッシュを格納するオブジェクトです。
class MyDataObject { // This object stores ALL DATA.
private:
    vValue data;
public:
    void setData(vValue data) {
        this->data = data;
    }
    vValue &getData() {
        return data;
    }
};
データ セグメントは、boost::iterator_range を使用してすべてのデータのサブセットとして作成されます。
class DataSegment { // This object points to a subset of all data using boost::iterator_range
private:
    rValue data;
public:
    void setData(rValue data) {
        this->data = data;
    }
    rValue& getData() {
        return data;
    }
};
実際のデータベースの実装:
class DB { // The database caches ALL DATA and then returns a subset using boost::iterator_range when asked for.
private:
    std::map<std::string, MyDataObject> cache;
public:
    DB() {
        //
    }
    MyDataObject loadIntoCache(std::string key) {
        vValue data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        MyDataObject obj;
        obj.setData(data);
        cache[key] = obj;
        return obj;
    }
    boost::shared_ptr<DataSegment> getMemoryEfficientSubset() {
        MyDataObject obj = loadIntoCache("bar"); // If bar is not in cache, load it.
        rValue data = obj.getData();
        boost::shared_ptr<DataSegment> segment(new DataSegment());
        rValue out = boost::make_iterator_range(data.begin() + 2, data.begin() + 7);
        segment->setData(out);
        return segment;
    }
};
テストコード:
int main() {
    DB *db = new DB();
    boost::shared_ptr<DataSegment> segment = db->getMemoryEfficientSubset();
    print_range(segment->getData()); // ERROR: segfault within print_range. Valgrind says "Invalid read of size 8"
    delete db;
    return 0;
}