Как этот код может вести себя так, как я видел?
У меня есть приложение C++, в котором произошла ошибка одноразового утверждения, которую я не могу воспроизвести. Вот код, который не удалось один раз:
unsigned int test(std::vector<CAction> actionQueue) {
unsigned int theLastCount = actionQueue.size() - 1;
std::vector<CAction>::const_reverse_iterator rItr = actionQueue.rbegin();
std::vector<CAction>::const_reverse_iterator rEndItr = actionQueue.rend();
for (; rItr != rEndItr; ++rItr, --theLastCount) {
const CAction &fileAction = *rItr;
if (fileAction.test()) {
continue;
}
return theLastCount;
}
assert(theLastCount == 0); // How could this fail?
return theLastCount;
}
Каким-то образом theLastCount не был равен нулю после завершения цикла.
Из моего чтения логики это должно быть невозможно, если:
- Другая сторона потока повлияла на actionQueue (что я не считаю возможным).
- Произошло некоторое временное повреждение памяти.
Я что-то упустил здесь, есть ли в моем коде ошибка? Обратите внимание, что в случае, когда я видел это, значение LastCount должно было быть инициализировано равным одному, поскольку вектор имел два элемента.
5 ответов
Я считаю, что если test() пройден для всех fileActions, theLastCount будет равен -1. Рассматривать:
theLastCount начинается с actionQueue.size() -1. Вы уменьшаете его один раз для каждого элемента в actionQueue, то есть теперь это actionQueue.size() - 1 - actionQueue.size() = -1. Думаю об этом. theLastCount хранит индекс текущего итератора. Но когда текущий итератор разыграен, то это один итератор перед началом массива, который равен -1.
Редактировать: О, это без знака. Но поскольку вы проверяете только равенство нулю, то переполнение не имеет большого значения.
Если ваше actionQueue пусто, то
unsigned int theLastCount = actionQueue.size() - 1;
установит theLastCount
до максимально возможного целого числа без знака. Внутренний цикл никогда не будет выполнен, потому что обратные итераторы равны друг другу (rbegin() == rend()
на пустые контейнеры), и поэтому вы нажмете утверждение с theLastCount
равным поразительно огромному числу.
Пожалуйста, скомпилируйте и запустите ваш код, прежде чем размещать его здесь! Во-первых, этот код не компилируется (я не говорю вам, почему - вы можете спросить свой компилятор). Во-вторых, ваше утверждение никогда не может быть успешным, потому что theLastCount всегда будет (unsigned int)-1.
void test(std::vector<CAction> actionQueue)
{
unsigned int theLastCount = actionQueue.size() - 1;
/** Omitted code ***/
{
/** Omitted code ***/
return theLastCount;
}
return theLastCount;
}
Забудьте об ошибке, которую вы не можете воспроизвести. Но здесь есть одна серьезная проблема. Тип возврата void
пока ты вернешься unsigned int
!! Как так?
Я думаю, вам нужно написать это:
assert(theLastCount == -1);//correct assert!
Это потому, что если test()
передать для всех элементов, тогда theLastCount должен стать -1. Поскольку элемента не осталось, и theLastCount всегда является допустимым индексом элемента, если элемент есть. Иначе оно должно стать -1.
ПРИМЕЧАНИЕ. Измените тип theLastCount
от unsigned int
в int
,
Что делать, если очередь пуста?
theLastCount
будет -1, а потом...:-)