падение при использовании вектора stl вместо оператора [] - PullRequest
3 голосов
/ 26 мая 2010

У меня есть метод следующим образом (из класса, который реализует интерфейс задачи TBB - в настоящее время не многопоточность, хотя) Моя проблема в том, что два способа доступа к вектору вызывают совершенно различное поведение - один работает, а другой заставляет целую программу взрываться очень эффектно (это плагин, и обычно хост будет обнаруживать сбой - но этот требует из программы хоста! Как я уже сказал, довольно эффектно)

void PtBranchAndBoundIterationOriginRunner::runOrigin(int origin, int time) const // NOTE: const method
{
    BOOST_FOREACH(int accessMode, m_props->GetAccessModes())
    {
        // get a const reference to appropriate vector from member variable
        // map<int, vector<double>> m_rowTotalsByAccessMode;
        const vector<double>& rowTotalsForAccessMode = m_rowTotalsByAccessMode.find(accessMode)->second;

        if (origin != 129) continue; // Additional debug constrain: I know that the vector only has one non-zero element at index 129

        m_job->Write("size: " + ToString(rowTotalsForAccessMode.size()));
        try {
            // check for early return... i.e. nothing to do for this origin 
            if (!rowTotalsForAccessMode[origin])    continue; // <- this works
            if (!rowTotalsForAccessMode.at(origin)) continue; // <- this crashes
        } catch (...) {
            m_job->Write("Caught an exception"); // but its not an exception
        }

        // do some other stuff
    }
}

Я ненавижу не задавать четко определенные вопросы, но сейчас моя лучшая формулировка: "WTF?"

Я компилирую это с Intel C ++ 11.0.074 [IA-32] с использованием Microsoft (R) Visual Studio версии 9.0.21022.8, и моя реализация vector имеет

const_reference operator[](size_type _Pos) const
{   // subscript nonmutable sequence

#if _HAS_ITERATOR_DEBUGGING
    if (size() <= _Pos)
    {
        _DEBUG_ERROR("vector subscript out of range");
        _SCL_SECURE_OUT_OF_RANGE;
    }
#endif /* _HAS_ITERATOR_DEBUGGING */
    _SCL_SECURE_VALIDATE_RANGE(_Pos < size());

    return (*(_Myfirst + _Pos));
}

(отладка итератора отключена - я почти уверен) и

const_reference at(size_type _Pos) const
{   // subscript nonmutable sequence with checking
    if (size() <= _Pos)
        _Xran();
    return (*(begin() + _Pos));
}

Таким образом, единственное отличие, которое я вижу, состоит в том, что при вызовах начинаются вместо простого использования _Myfirst - но как это может вызвать такую ​​огромную разницу в поведении?

ОБНОВЛЕНИЕ :

Индекс находится в пределах диапазона - размер распечатывается как 377, а индекс ограничен до 129.

Переменная-член имеет запись, соответствующую accessMode

Все это было заключено в следующее, чтобы уточнить предложение @nikko:

map<int, vector<double>>::const_iterator it = m_rowTotalsByAccessMode.find(accessMode);
if (it != m_rowTotalsByAccessMode.end())
{
    ...

ОБНОВЛЕНИЕ Я обновил свой компилятор до последней версии 11.1.065, и этого больше не происходит. Похоже, это было где-то странно.

Ответы [ 3 ]

3 голосов
/ 26 мая 2010

Я не видел, где вы проверяли, что rowTotalsForAccessMode действителен. Возможно, ваш "m_rowTotalsByAccessMode.find (accessMode)" не работает.

Вы должны проверить результат вашего .find () по сравнению с итератором end (), чтобы убедиться, что он действителен

0 голосов
/ 27 мая 2010

Я терпеть не могу отвечать на свои вопросы, но, похоже, в такой ситуации это необходимо. Как говорится в обновлении, я скачал и установил последний компилятор Intel C ++ и перекомпилировал его с нуля, что, похоже, решило проблему. Я также перестроил весь проект с нуля, используя компилятор 11.0.074, чтобы исключить повреждение одного из двоичных файлов; даже чистая сборка приводит к сбою!

Я собираюсь следить за этим на форумах Intel, спасибо всем, кто потратил некоторое время и усилия на решение этой проблемы.

0 голосов
/ 26 мая 2010

Не можете ли вы пошагово выполнить программу в отладчике (в at) и посмотреть, что вызывает сбой? Есть два варианта:

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