2012-01-14 2 views
4

Я намеренно сделал итератор превышать размер std::vector как,оценка проверка итератора в режиме выпуска (C++)

for (std::vector <Face>::iterator f = face.begin(); 
      f!=face.end()+5; 
       ++f) 
{ 
    // here I try to access (*f).P 
    // note that I added 5 to the face.end() 
} 

Я не сталкивался с какой-либо ошибки ни при компиляции и времени выполнения. Как я могу это предотвратить?

+4

Просто не делайте этого? Что касается обнаружения, выполните поиск * проверенных итераторов *. –

+2

Отладочные сборки обычно ловят то, что – pezcode

+0

Я использую Release из-за необходимости во время выполнения. – Shibli

ответ

4

Если вы хотите проверить доступ к элементам vector, вы можете использовать функцию at, которая выдает исключение std::out_of_range в случае нарушения границы. Пример:

for (std::vector<Face>::size_type i = 0; 
      i != face.size()+5; 
       ++i) 
{ 
    face.at(i).f(); 
} 

В стандарте не указаны проверенные итераторы. Формулировка в стандарте заключается в том, что доступ к недействительному итератору приводит к неопределенному поведению. Но многие реализации предоставляют проверенные итераторы. Если переносимость не вызывает беспокойства, вы можете использовать один из этих проверенных итераторов. Например, в режиме отладки MSVC vector<T>::iterator является проверенным итератором. В режиме Release, однако, это всего лишь typedef для T*

+0

Вы можете применить 'at' в моем коде, пожалуйста, в качестве примера – Shibli

+0

@Shibli: См. Мое редактирование –

+0

В режиме отладки он видит ошибку, не используя' at'. Поскольку я не понял твое последнее предложение, в режиме выпуска я должен использовать 'at' для проверки? – Shibli

1

Какой компилятор C++ вы используете? VC10 (т.е. C++ компилятор в VS2010) в отладочных правильно идентифицирует проблему:

// Compile with: 
// cl /EHsc /W4 /nologo /D_DEBUG /MDd test.cpp 


#include <iostream> 
#include <string> 
#include <vector> 


class Face 
{ 
public: 
    std::string Name; 

    explicit Face(const std::string & name) 
     : Name(name) 
    {} 
}; 


int main() 
{ 
    std::vector<Face> faces; 
    faces.push_back(Face("Connie")); 
    faces.push_back(Face("John")); 

    for (
     std::vector <Face>::iterator f = faces.begin(); 
     f != faces.end() + 5; 
     ++f) 
    { 
     std::cout << f->Name << std::endl; 
    } 

    return 0; 
} 

При выполнении получившийся exe-файл, диалоговое окно ошибки ап показал со следующим сообщением об ошибке:

Expression: вектор итератор + смещение из диапазона

+0

Он дал ту же ошибку во время выполнения в режиме отладки. Спасибо. – Shibli

+0

@ Шибли: Пожалуйста. Реализация STL, которая поставляется с MS Visual C++, отлично подходит для задач отладки с проверенными итераторами и поддержкой отладки итератора. –

0

Для версии стандартной библиотеки C++, вы не получите строить в проверки границ на вашем итераторы (или другие операции, которые могут быть сняты), поскольку они будут сравнительно медленными. Однако это не означает, что вам нужно скомпилировать в режиме отладки: насколько я понимаю режим отладки libstdC++, его можно использовать, когда включена компиляция с оптимизацией компилятора. Я подозреваю, что это верно для других проверенных реализаций STL, потому что проверенный код, как правило, просто управляется настройкой некоторых макросов соответствующим образом. Для этого вам нужно найти соответствующие настройки макросов и настроить их соответствующим образом с помощью того, что вы используете для создания кода.

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