не может разыменовать значение инициализированного итератора - PullRequest
0 голосов
/ 03 сентября 2018

Я играл с предлагаемой 2d графической библиотекой для C ++, старая реализация, которую я получил отсюда 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. Что я делаю не так?

Ответы [ 3 ]

0 голосов
/ 03 сентября 2018

Чтобы вставить элементы в конец вектора, используя std::copy, вам нужно использовать std::back_inserter. Если вы не используете back_inserter, то перед вызовом std::copy.

убедитесь, что ваш вектор достаточно большой.
0 голосов
/ 03 сентября 2018

Вы предоставляете пустое std::vector в качестве пункта назначения при вызове std::copy(), следовательно, оно будет потенциально слишком маленьким, чтобы соответствовать исходным данным, и поэтому вы получите неопределенное поведение . Чтобы решить это непосредственно, вам нужно передать std::back_inserter в качестве 3-го аргумента std::copy(). Таким образом, он будет добавляться к std::vector при копировании в него, таким образом гарантируя, что он будет иметь правильный размер - как показано в примере здесь внизу .

Сказав, что, если все, что вам нужно, это скопировать содержимое файла в std::vector, то это будет широко используемый и широко рекомендуемый шаблон, использующий 4-ю перегрузку здесь :

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. 2-й аргумент - это построенный по умолчанию std::istreambuf_iterator, который удобно использовать в качестве end итератора этого или любого такого потока.

0 голосов
/ 03 сентября 2018

При вызове copy вектор алгоритма img_data пуст, а когда вы записываете данные в этот вектор, вы получаете ошибку сегмента. Если вы не знаете, какой размер входных данных нужно записать, вы должны использовать back_inserter для добавления данных в ваш вектор:

std::copy(std::istream_iterator<unsigned char>(file) , 
std::istream_iterator<unsigned char>(), std::back_inserter(img_data));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...