Почему мой векторный код утверждает?Что вообще такое утверждение?

StackOverflow https://stackoverflow.com/questions/817429

  •  03-07-2019
  •  | 
  •  

Вопрос

Что такое «утверждение» или, точнее, как мне избавиться от ошибки.Когда я создаю вектор указателей на класс с членом данных int x, а затем делаю это:

for(I=antiviral_data.begin();I<antiviral_data.end();I++)
{
    if((*I)->x>maxx)
    {
        antiviral_data.erase(I);
    }
}

И запустив программу, я не получаю ошибок до тех пор, пока x не станет больше maxx, и я не использую .erase(), после чего получаю эту ошибку:

Утверждение отладки не выполнено!

Программа:...Мои документы\файл O.exe:...include\vector Строка:116

Выражение:(«this->_Has_container()», 0)

Для получения информации о том, как ваша программа может вызвать сбой утверждения, см. В визуальной документации C ++ по утверждениям.

(Нажмите «Повторить», чтобы отладить приложение)

[Прервать][Повторить][Игнорировать]

Кроме того, если я попытаюсь использовать cout:

cout<<(*antiviral_data.begin())->x<<endl;

Я получаю эту ошибку:

Утверждение отладки не выполнено!

Программа:...Мои документы\файл O.exe:...include\vector Строка:98

Выражение:векторный итератор не отслеживается

Для получения информации о том, как ваша программа может вызвать сбой утверждения, см. В визуальной документации C ++ по утверждениям.

(Нажмите «Повторить», чтобы отладить приложение)

[Прервать][Повторить][Игнорировать]

Может кто-нибудь сказать мне, почему я не могу ИСПОЛЬЗОВАТЬ какие-либо данные в векторе и как это исправить?

ТАКЖЕ:antiviral_data — это вектор указателей с одним элементом:

antiviral_data.push_back(new aX1(player.x,player.y,'>'));

Если это поможет.

Это было полезно?

Решение

Наиболее вероятная причина, по которой вы получаете это утверждение, заключается в том, что вы увеличиваете I после стирания.Вместо этого попробуйте это:

for(I=antiviral_data.begin();I!=antiviral_data.end();)
{
    if((*I)->x>maxx) I=antiviral_data.erase(I); else ++I;
}

Смотрите также http://www.cppreference.com/wiki/stl/vector/erase , искать недопустимые итераторы на этой странице.

Другие советы

Утверждение обычно представляет собой выражение, введенное разработчиком в целях отладки и контроля ошибок: вы помещаете в свой код различные «проверки работоспособности», и если проверка не достигнута, программа аварийно завершает работу.

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

Утверждения обычно появляются только в отладочной версии кода (если вы используете Visual C++, вы можете скомпилировать его для отладки и выпуска).Хотя компиляция в режиме выпуска приведет к устранению результатов, это очень плохая идея, поскольку у вас все равно будут ошибки и, вероятно, очень плохие результаты.

Где-то в реализации Vector (это стандартно), а именно в строке 98, есть утверждение.Если у вас есть доступ к векторному коду, посмотрите, что такое утверждение, или выполните отладку до этого момента.Это может указывать на ошибку в реализации вектора или в коде, вызывающем вектор.

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

Проблема в стирании вызова.Вы перебираете контейнер и в то же время стираете из него элементы.После стирания ваш итератор становится недействительным.Если вы хотите удалить элементы определенного значения из вектора, используйте стирание с алгоритмом удаления_if.Это известно как идиома «стирание-удаление» и очень хорошо объяснено в книге Скотта Мейера «Эффективный STL».Вы также можете обратиться к этому вопросу Удаление элементов из вектора Чтобы получить больше информации.

У вас уже есть пара хороших ответов о том, что такое утверждение и почему оно срабатывает в вашем коде.Теперь вы можете рассмотреть возможность использования алгоритмов STL для двухпроходного стирания.

namespace {
   struct exceeds : public std::unary_function< TheUnknownType*, bool >
   {
      exceeds_max( int max ) : maxx( max ) {}
      bool operator()( TheUnknownType* data ) {
         return data->x < max;
      } 
   private:
      int maxx;
   };
}
void your_function()
{
   std::vector< TheUnknownType* >::iterator new_end;
   new_end = std::remove_if( antiviral_data.begin(), antiviral_data.end(), exceeds(maxx) );
   antiviral_data.remove( new_end, antiviral_data.end() );
}

Основное преимущество заключается в том, что стирание элементов в векторе — дорогостоящая операция.Для каждого стертого элемента все элементы от этой позиции до конца вектора должны быть перемещены на одну позицию к началу.Второй элемент, который вы стираете, вызовет второе перемещение всех элементов с этого момента...СТЛ удалить_если алгоритм выполняет перемещения только один раз до конечной позиции, возвращая итератор одно прошлое последний элемент не удаленный элемент.Затем вы можете выполнить один единственный std::vector<>::remove, который не потребует перемещения элементов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top