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

问题描述 投票:0回答:4

我正在玩建议的 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 语句中抛出异常。我做错了什么?

c++ iterator
4个回答
8
投票

您在调用

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

话虽如此,如果您想要的只是将文件的内容复制到

std::vector

中,那么这将是一种常用且广泛推荐的模式,采用第四个重载
此处

auto loadimg(std::ifstream &file) { std::vector<unsigned char> img_data( std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()); return img_data; }
这作为构造函数的第一个参数(类型为

std::istreambuf_iterator

)格式良好,满足LegacyInputIterator
。第二个参数是默认构造的 
std::istreambuf_iterator
,它可以方便地用作此流或任何此类流的
end
迭代器。
    


6
投票
copy

算法向量

img_data
时,向量为空,并且当您向该向量写入数据时,会出现段错误。当您不知道要写入的输入数据的大小是多少时,您应该使用
back_inserter
将数据附加到向量中:

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



1
投票
std::copy

将元素插入向量的后面,您需要使用

std::back_inserter
。如果不使用
back_inserter
,您需要在调用
std::copy
之前确保向量足够大。
    


0
投票

case SC_PrintFloat: { char result[255]; float* num = (float*)machine->ReadRegister(4); int length = floatToChar(*num, result); gSynchConsole->Write(result, length); IncreasePC(); return; }`

当我编写测试程序时:
float *a; a = ReadFloat(); *a = 1.1; PrintFloat(a);

我收到错误,当我通过取消引用指针来分配浮点数时,程序终止。这是为什么?

© www.soinside.com 2019 - 2024. All rights reserved.