проверка границ для итератора в режиме Release (c ++) - PullRequest
4 голосов
/ 14 января 2012

Я специально сделал итератор, чтобы он превышал размер std::vector, например,

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()
}

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

Ответы [ 3 ]

4 голосов
/ 14 января 2012

Если вы хотите проверить доступ к элементам 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*

1 голос
/ 14 января 2012

Какой компилятор 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-файла появляется диалоговое окно с сообщением об ошибке:

Выражение: векторный итератор + смещение вне диапазона

0 голосов
/ 15 января 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...