我正在玩建议的 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 语句中抛出异常。我做错了什么?
您在调用
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;
}
这作为构造函数的第一个参数(类型为)格式良好,满足LegacyInputIterator
。第二个参数是默认构造的 std::istreambuf_iterator
,它可以方便地用作此流或任何此类流的 end
迭代器。copy
算法向量
img_data
时,向量为空,并且当您向该向量写入数据时,会出现段错误。当您不知道要写入的输入数据的大小是多少时,您应该使用 back_inserter
将数据附加到向量中:std::copy(std::istream_iterator<unsigned char>(file) ,
std::istream_iterator<unsigned char>(), std::back_inserter(img_data));
std::copy
将元素插入向量的后面,您需要使用
std::back_inserter
。如果不使用 back_inserter
,您需要在调用 std::copy
之前确保向量足够大。 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);
我收到错误,当我通过取消引用指针来分配浮点数时,程序终止。这是为什么?