无法取消引用值初始化的迭代器

时间:2018-09-03 13:40:08

标签: c++ iterator

我正在研究拟议的C ++ 2D图形库,这是我从这里https://github.com/cristianadam/io2d获得的旧实现,我试图在显示表面上渲染图像表面,然后使用加载到无符号字符向量中std :: copy算法

auto loadimg(std::ifstream  &file) {
    std::vector<unsigned char> img_data{};
    std::copy(std::istream_iterator<unsigned char>(file) , 
    std::istream_iterator<unsigned char>(), img_data.begin());
    return img_data;
}

我也尝试过std::move

loadimg函数的客户端是这样的

std::ifstream file("packagelevel.png");
img_surf.data(loadimg(file));

尽管该程序使用Visual Studio 2017进行编译。但是在调试时出现错误“无法取消引用值初始化迭代器” 并且在loadimg return语句上引发了异常。我在做什么错?

3 个答案:

答案 0 :(得分:3)

当调用copy算法向量img_data为空时,将数据写入该向量时会出现段错误。当您不知道要写入的输入数据的大小时,应使用back_inserter将数据追加到向量中:

std::copy(std::istream_iterator<unsigned char>(file) , 
std::istream_iterator<unsigned char>(), std::back_inserter(img_data));

答案 1 :(得分:3)

您在调用std::vector时提供了一个空的std::copy()作为目的地,因此它可能太小而无法容纳源数据,因此您会得到未定义的行为。要直接解决此问题,您需要将std::back_inserter作为第三个参数传递给std::copy()。这样,它将在复制到std::vector时附加到std::vector上,从而确保其大小正确-如示例here at the bottom所示。

话虽如此,如果您只想将文件的内容复制到auto loadimg(std::ifstream &file) { std::vector<unsigned char> img_data( std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()); return img_data; } 中,那么这将是一种普遍使用并被广泛推荐的模式,采用第四重载here

std::istreambuf_iterator

这很好地构成了构造函数的第一个参数(类型为std::istreambuf_iteratorsatisfies LegacyInputIterator。第二个参数是默认构造的getNow,可以方便地标记此流或任何此类流中的最后一个迭代器。

答案 2 :(得分:0)

要使用std::copy将元素插入向量的后面,您需要使用std::back_inserter。如果不使用back_inserter,则需要在调用std::copy之前确保向量足够大。