Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can't dereference value initialized iterator

Tags:

c++

iterator

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?

like image 774
Ogunleye Ayowale Pius Avatar asked Sep 03 '18 13:09

Ogunleye Ayowale Pius


2 Answers

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.

like image 152
Geezer Avatar answered Sep 19 '22 12:09

Geezer


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));
like image 22
rafix07 Avatar answered Sep 20 '22 12:09

rafix07