Вопрос

Поэтому я делаю змею игру с телепортатами и обычными мышами. У меня был цикл работает так:

while(snake.alive() && miceEaten < micePerLevel)
{
    displayInfo(lives, score, level, micePerLevel - miceEaten);
    //some code
    if(miceEaten())
    {
        //update score...
    }
    //more stuff...
}

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

while(snake.alive() && miceEaten < micePerLevel)
{
    //some code
    if(miceEaten())
    {
        //update score...
    }
    //more stuff...
    displayInfo(lives, score, level, micePerLevel - miceEaten);
}

И телепортирует перестать работать! Программа сбивается всякий раз, когда змея достигает телепортации. И displayInfo использует следующий код:

stringstream s;
s << "LEVEL " << left << setw(12) << level << "LIVES: " << setw(12) << lives << "MICE LEFT: " << setw(12) << miceLeft
    << "SCORE: " << setw(13) << score;
printLine(0, s.str(), WHITEONBLUE);

Где printLine Только имеет А. color_set, mvprintw, и refresh(). Отказ Нечего делать с телепортами. Странный.

Поэтому я пошел в функцию змеи, где змея получает свое следующее место от телепортации:

    body.push_back(teleports[overlap(next)]->teleportFrom(dir)); //next is a Location object

Где teleports[overlap(next)]->teleportFrom(dir) Возвращает местоположение, чтобы змея должна быть телепортирована. В попытке понять, почему это было разрушено (возможно, Teleport Возвращал некоторое расположение без экрана?), Я добавил следующие 3 строки перед вышеуказанной линией:

    Location l = teleports[overlap(next)]->teleportFrom(dir);
    mvprintw(1, 0, "(%i, %i)", l.x, l.y);
    refresh();

И проблема исчезает!

Не только это, но я должен иметь эти три линии. Если я комментирую mvprintw(1, 0, "(%i, %i)", l.x, l.y);, или refresh();, или оба, оба, программа вылетает как до достижения телепортации.

Любые идеи о том, что могут вызывать это поведение?

ОБНОВИТЬ: Я попытался удалить все предупреждения (которые были в основном предупреждения о сравнениях подписанных / беззнаковных чисел), но только 1 остается до сих пор:

warning: reference to local variable 'other' returned

И код:

Location& Location::operator = (Location other)
{
    if(this == &other)
        return other;
    x = other.x;
    y = other.y;
    return *this;
}

Что я делаю, чтобы исправить это предупреждение?

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

Решение

Создайте оператора вашего назначения, как это:
Вы всегда должны вернуться * это (даже если они были равны). Но они никогда не будут, так как вы создали локальную копию (так что это не ваша ошибка).

Location& Location::operator = (Location const& other)
{
    // Does it really matter if you assign to self?
    x = other.x;
    y = other.y;
    return *this;
}

Стандартная копия и своп казались немного излишним для такого простого класса.

Придавать Вы должны исправить все предупреждения (даже если они так же просто, как несоответствие без знака). Если вы не исправляете их, вы станете невосприимчивым к их потенции и не замечу реальную проблему, потому что она окружена предупреждением, что вы игнорируете. Так что исправьте их все (Ai всегда включайте флаг, который заставляет компилятор обрабатывать все предупреждения в качестве ошибок, чтобы код не скомпилировал, если есть какие-либо предупреждения).

Правильный способ реализации оператора присваивания (или наиболее общепринятый путь). Это использовать копию и своп IDIOM:

// notice the parameter is passed by value (i.e. a copy).
// So the copy part is aromatically taken care of here.
// So now you just need tom implement the swap() part of the idiom.
Location& Location::operator = (Location other)
{
    this->swap(other);
    return *this;
}

void Location::swap(Location& other)
{
    std::swap(x, other.x);
    std::swap(y, other.y);
}

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

Location& Location::operator = (Location other)
{
    if(this == &other)
        return other;
    x = other.x;
    y = other.y;
    return *this;
}

Это возвращает ссылку. Когда функция возвращается, что происходит с other? (Это умирает, и вы ничего не ссылаетесь.) Так как это класс, с которым вы имеете дело со своей проблемой, это, вероятно, является причиной. Переоформление окружающего кода покидает стек в определенном состоянии, где относятся к мертвой переменной «работает».

Изменить его в return *this, или просто удалите чек в целом. (Назначение двух переменных без ветки, вероятно, всегда будет работать быстрее, чем добавление ветви, на современном процессоре.)

(Вы также должны вообще принимать параметр по ссылке, а не по значению.)

Вы проверили свой код, который вызывает эту аномалию? То Гейзенбаг Явления цитируются здесь:

Одним из распространенных примеров является ошибка, возникающая в программе, которая была скомпилирована с оптимизирующим компилятором, но не в той же программе при компиляции без оптимизации (например, для генерации версии отладки)

Вот несколько рекомендаций:

  • Состояние гонки? Вы используете темы?
  • Указатель переполняет границу где-то?
  • Запустите свой код через валгринда Для мониторинга для любых необычных / ошибочных изменений в буферах памяти где-то

Еще одна цитата:

Одной из распространенных причин для поведения HEISENBUG - это то, что выполнение программы в режиме отладки часто очищает память до начала программы, а также заставляет переменные в местах стека вместо того, чтобы держать их в регистрах. Эти различия в исполнении могут изменить влияние ошибок, связанных с преобразованием доступа к членам или неверным предположениям о начальном содержании памяти. Другая причина заключается в том, что отладчики обычно предоставляют часы или другие пользовательские интерфейсы, которые вызывают дополнительный код (например, доступ к свойствам), которые могут быть выполнены, которые могут, в свою очередь, измените состояние программы. Еще одна причина - это Фаннданго на ядре, эффект указателя, не хватающей границ. В C ++ многие Гейзенбаги вызваны неинициализированными переменными.

Убедитесь, что переключатели выключены - нет оптимизации, полной информации отладки, очистить любые существующие сборки, перезапустите IDE и снова перекомпилировать ....

Прежде всего, ваше местоположение :: Оператор = должен быть таким вместо этого:

Location& Location::operator = (const Location &other)
{
    if(this == &other)
        return *this;
    x = other.x;
    y = other.y;
    return *this;
}

Однако, что, вероятно, не объясняет авария. Плохие указатели на стеке здесь не хватает большинства архитектур (при условии, что х и у int).

Теперь тогда это Мандельбуг, а не Гейзенбаг. У вас есть кто-то еще, где-то развращает память. Удачи.

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