I was playing around the proposed 2d graphics library for C++, the old implementation that I got from here https://github.com/cristianadam/io2d, I am trying to render an image surface on a display surface which i load into vector of unsigned char using the std::copy algorithms
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;
}
I tried std::move
too.
And the client for the loadimg function goes like this
std::ifstream file("packagelevel.png");
img_surf.data(loadimg(file));
although the program compiles using visual studio 2017. But I am getting the error at debug "Can't derefence value initialize iterator" and the exception was thrown at the loadimg return statement.What am I doing wrong?
You're providing an empty std::vector
as the destination while calling std::copy()
, hence it'll potentially be too small to fit the source data, and so you get undefined behavior. To solve this directly you need to pass a std::back_inserter
as the 3rd argument to std::copy()
. That way it will append to the std::vector
as it copies into it, thus making sure it will have the right size -- as shown in the example here at the bottom.
Having said that, if all you want is copying the file's content into a std::vector
then this would be a commonly used and widely recommended pattern, employing the 4th overload here:
auto loadimg(std::ifstream &file) {
std::vector<unsigned char> img_data(
std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
return img_data;
}
This is well formed as the 1st argument given to the constructor (being of type std::istreambuf_iterator
) satisfies LegacyInputIterator
. The 2nd argument is a default constructed std::istreambuf_iterator
, which would conveniently serve as the end
iterator of this or any such stream.
While calling copy
algorithm vector img_data
is empty, and when you are writing data to this vector you are getting seg fault. When you don't know what is the size of input data to be written you should use back_inserter
to append data to your vector:
std::copy(std::istream_iterator<unsigned char>(file) ,
std::istream_iterator<unsigned char>(), std::back_inserter(img_data));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With