2015-08-25 2 views
-5
vector<int> iV2_func{2, 3, 4, 5}; 
drucke(iV2_func); 
    for (j=0; j<=iV2_func.size(); j++) { 
    iV2_func[j] = quadfunc(iV2_func[j]+1); 
} 
drucke(iV2_func); 

В настоящее время я тренируюсь для своего предстоящего экзамена C++, и с тех пор, как я вырос с Java, я не знаком со всеми обычаями C++. Данный код находится в main() -Метах, все необходимое было включено и т. Д. Задача заключалась в обнаружении ошибок в шести циклах, которые использовали различные средства для умножения параметра с самим собой, например макроса, шаблона, встроенная функция и т. д. drucke() печатает одиночные элементы вектора. Этот цикл for здесь явно за пределами границ, но поскольку метод .at() -Method не используется, исключение не генерируется, и вместо этого мы получаем неопределенное поведение.Векторный оператор [] вне диапазона приводит к сбою?

Когда я запускаю программу, программа вылетает после все линии были напечатаны. Даже для петель после этот контур прямо здесь проходит, и все печатается. Похоже, что ошибка возникает в конце метода main(), а не когда программа обращается к индексу, который выходит за пределы диапазона, но ошибка определенно лежит в этом индексе, потому что программа не сбой в противном случае. Итак, как именно, что программа, похоже, работает с этим кодом, но все же падает в конце?

+7

имеет неопределенное поведение, а это означает, что буквально * что-либо может случиться. –

+0

_Vector 'operator []' вне диапазона приводит к сбою_ Я знал, что это будет хорошо! – Tas

+0

Код с ошибками в нем не будет вести себя так, как вы ожидаете. Вот почему мы исправляем ошибки. –

ответ

1

Так как же именно программа, похоже, работает с этим кодом, но все же падает в конце?

Скорее всего, вы скомпилировали свою программу в конфигурации отладки. В отладочных сборках «периметр» выделенных областей памяти часто заполняется канарскими значениями, так что записи OOB могут быть обнаружены при освобождении памяти. Когда такая убитая канарейка обнаружена, дезактиватор памяти прекратит выполнение программы.

Зачем нужна канарейка? Потому что на современных ОС распределение памяти и защита происходит только с гранулярностью страницы, обычно 4k. Таким образом, до тех пор, пока ваш доступ к памяти остается в пределах отображаемого OS-сопоставления (что кратно размеру страницы), ОС не может обнаружить незаконный доступ. Однако распределители памяти будут распределять распределения в пределах этих страниц, и поскольку в этом регионе нет защиты между объектами, доступ к OOB, который сжимает «соседей», трудно обнаружить. Следовательно, канарейские значения, так что в развитии можно получить доступ к OOB.

+1

OOB = Out Of Bounds. – nwp

+0

Так что в основном это мера безопасности, которая обнаруживает, что что-то было написано OOB. Кажется, я понял это сейчас. Спасибо! – Grougal

+0

@Grougal: Не столько функция безопасности, сколько помощник для отладки.Не полагайтесь на это поведение, потому что это реализация определена, и только там, в качестве суда, чтобы вы знали о проблеме с вашим кодом. – datenwolf

Смежные вопросы