Изменение значения параметра C ++ между кадрами стека в std :: vector

Я столкнулся с действительно странной ошибкой, которую, надеюсь, кто-нибудь сможет объяснить. У меня есть простой std::vector<V3x>, где V3x - трехмерный вектор (тип линейной алгебры). Следующий код вызывает исключение std::length_error:

std::vector<V3x> vertices;
int vertexCount = computeVertexCount();
vertices.resize(vertexCount); // throws std::length_error

Я проверил, что computeVertexCount() возвращает значение 35, что намного меньше vector::max_size(), поэтому он не запрашивает слишком много памяти.

Я проследил исключение до определения std::vector, до следующих двух функций.

void resize(size_type _Newsize, _Ty _Val)
    {   // determine new length, padding with _Val elements as needed
    if (size() < _Newsize)
        // NOTE: here, _Newsize - size() = 35
        _Insert_n(end(), _Newsize - size(), _Val); 
    else if (_Newsize < size())
        erase(begin() + _Newsize, end());
    }

void _Insert_n(const_iterator _Where,
    size_type _Count, const _Ty& _Val)
    {   // insert _Count * _Val at _Where
        // NOTE: here, _Count = 3435973836
        ...
    }

Поэтому, когда параметр _Count передается между resize() и _Insert_n(), значение изменяется с 35 на 3435973836. Я предполагаю, что память каким-то образом была повреждена, но я понятия не имею, как это могло быть.

В качестве дополнительного контекста на случай, если это часть проблемы, этот код находится в подключаемом модуле .dll, который я загружаю из Softimage XSI.

Кто-нибудь знает, что может вызвать подобное?

РЕДАКТИРОВАТЬ: РЕШЕНИЕ

nobugz, я мог бы поцеловать тебя.

Размер std :: vector менялся внутри моей .dll из-за _HAS_ITERATOR_DEBUGGING в VS2008. Поиск привел меня к кто-то с такой же проблемой, и она была исправлена ​​добавлением следующего в начало моего проекта:

// fix stack corruption errors caused by VS2008
#define _HAS_ITERATOR_DEBUGGING 0
#define _SECURE_SCL 0

person eplawless    schedule 11.01.2009    source источник
comment
это std :: vector ‹V3x› вершины; неужели локальная переменная? в противном случае он вполне может быть еще не создан (из-за фиаско статической инициализации)   -  person Johannes Schaub - litb    schedule 11.01.2009
comment
Имеет ли vertices.resize (vertexCount); нужен второй аргумент?   -  person Mr.Ree    schedule 11.01.2009


Ответы (5)


Значение 3435973836 является значимым. В шестнадцатеричном формате это 0xcccccccc. Это значение, присвоенное локальным переменным в режиме отладки кодом инициализации кадра стека. Когда вы увидите это во время отладки, вы скажете «ах, переменная не инициализирована». Может быть, это приблизит вас к решению этой проблемы.

Вы упоминаете DLL. Это тоже актуально. Отладка итератора может вызвать у вас проблемы, вы не можете смешивать код, который отключил его, с кодом, который этого не делает. Поскольку DLL, вероятно, скомпилирована без нее, попробуйте #define _HAS_ITERATOR_DEBUGGING 0.

person Hans Passant    schedule 11.01.2009
comment
Всегда смотрите на шестнадцатеричное представление неожиданных очень больших значений. Они часто говорят вам, что вы ушли в пустошь, как эта. - person Rob K; 12.01.2009

Всякий раз, когда параметр или локальная переменная изменяется неожиданно, есть большая вероятность, что это связано с повреждением стека. Это может произойти всякий раз, когда вы используете неинициализированную локальную переменную или храните данные за пределами памяти, выделенной для локальной строки или массива.

Простой способ отладить это:

  1. Загрузите вашу программу в отладчик.
  2. Вставьте точку останова в первую строку кода в вызывающей ошибку функции.
  3. Выполняйте программу, пока она не достигнет точки останова.
  4. Установите наблюдение за неожиданно изменяющейся переменной.
  5. Пошагово выполняйте функцию, пока не произойдет неожиданное изменение.

Изменение произойдет при записи нераспределенной (или неправильно выделенной) памяти. Целью записи является вызывающая нарушение переменная.

person Adam Liss    schedule 11.01.2009

опубликованный код правильный, и вы можете предположить, что std :: vector не содержит ошибок. воспроизвести исключение в максимально чистой среде (новый пустой проект). может это быть что-то тупое вроде этого в ComputeVertexCount ()?

person Dustin Getz    schedule 11.01.2009

Я предлагаю просмотреть параметры C ++, настроенные для задействованных проектов. Убедитесь, что все они имеют одинаковые настройки выравнивания и времени выполнения. Вы участвуете в создании .DLL?

person Henk    schedule 11.01.2009