#c #stl
#c #stl
Вопрос:
привет, ребята, я покажу три кода 1 и 2, которые работают одинаково, но третий не работает. Я хочу понять, почему не работает или почему работают два других? (функция strrand выдает случайную строку)
1.
int main(){
vector<string> svec(50);
randomize();
generate_n(svec.begin(), 20, strrand);
display(svec.begin(), svec.end());
return 0;
}
2.
int main() {
vector<string> svec;
randomize();
generate_n(back_inserter(svec), 20, strrand);
display(svec.begin(), svec.end());
return 0;
}
3.
int main(){
vector<string> svec;
randomize();
generate_n(svec.begin(), 20, strrand);
display(svec.begin(), svec.end());
return 0;
}
Ответ №1:
Третий имеет неопределенное поведение. В первом вы указываете размер вектора, в котором вы определяете вектор. Это означает, что он начинается как вектор из 50 инициализированных по умолчанию (пустых) строк. Затем вы перезаписываете эти строки своими случайными строками.
Во втором случае вы используете a back_insert_iterator
для добавления строк в вектор по отдельности.
В третьем случае вы начинаете с пустого вектора и пытаетесь использовать (недопустимый) итератор до его (несуществующего) начала. Затем вы записываете 20 строк, начиная с любого места в памяти, на которое ссылается его (случайное) начальное значение. Однако вы никогда фактически не вставляли строку в вектор. Вектор обычно ведет подсчет количества элементов, которые он содержит в данный момент; в вашем третьем случае это будет начинаться с 0 и оставаться 0 повсюду. Когда вы пытаетесь показать «содержимое», вы ничего не должны получить (хотя, поскольку у вас уже было неопределенное поведение на тот момент, все возможно — особенно, если некоторые данные, которые вы написали, случайно перезаписали часть внутренних данных вектора.
У вас есть немного более тонкая (но не менее проблематичная) версия хорошо известных ошибок новичков, таких как:
char *s;
strcpy(s, "This will give UB");
Комментарии:
1. во втором случае, когда я использую back_insert_iterator , инициализирует ли back_insert_iterator векторный класс?
2. теперь я понял …! спасибо ..! back_insert_iterator использует в нем push_back .