c ++ std :: vector.insert падает при отладке, но работает при выпуске - PullRequest
2 голосов
/ 01 декабря 2011

Моя программа аварийно завершает работу в этой строке, но только в отладочной сборке, она отлично работает в сборке выпуска.

m_lstIds.insert(m_lstIds.begin() + indexInsert, ID);

'm_lstIds' является std :: vector of int, 'ID' является int. Когда программа вылетала, у m_lstIds было 3 элемента (1, 2, 3). indexInsert был '0', а ID был '0'.

Сообщение об ошибке гласит:

Expression: vector iterator + offset out of range

Я работаю в Visual Studio 2010; Я предполагаю, что это как-то связано с плохими настройками проекта, которые противоречили оптимизации STL.

Edit: Когда я сказал: «работает над выпуском», я имел в виду, что если я сделаю std::cout<<m_lstIds[i] для i = 0..3, я фактически напечатаю 0,1,2,3. В отладочной сборке он просто вылетает при попытке вставить.

Edit2: Я нашел ответ! Спасибо всем за помощь.

Вот самое короткое воспроизведение. Проблема заключается в функции memset, которую я вызываю в конструкторе. Поскольку конструктор m_lstItem был вызван до memset, он сотрет все данные в векторе, которые позволили insert работать правильно.

Что действительно интересно, так это то, как это работало в релизе, но не в отладке. Было бы здорово, если бы кто-то мог объяснить эту часть.

struct SimpleList
{
  SimpleList()
  {
    memset(this, 0, sizeof(SimpleList));
    m_lstItem.push_back(0);
    m_lstItem.push_back(1);
    m_lstItem.push_back(2);
  }

  void Crash()
  {
    m_lstItem.insert(m_lstItem.begin() + 0, 3);
  }

  std::vector<int>m_lstItem;
};

int main(int argc, char** argv[])
{ 
  SimpleList sl;
  sl.Crash();
  return 0;
}

Ответы [ 2 ]

4 голосов
/ 01 декабря 2011

memset(this, 0, sizeof(SimpleList)); небезопасно, когда ваша структура не POD .

Из-за члена std::vector<int>m_lstItem; ваша структура не является POD.

Поэтому использование memset в этом случае небезопасно и приводит к неопределенному поведению Другими словами: все может случиться! И все, что включает в себя работу, как ожидалось ...

Мой совет: не используйте memset в C ++, если вы полностью не знаете, что делаете.

0 голосов
/ 01 декабря 2011

Я думаю, indexInsert не 0, когда программа работает.И вектор будет генерировать исключение, когда вектор выходит за пределы диапазона в режиме отладки, а в режиме RELEASE - нет.Так что покажи полный код.

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