C++ Предыдущий указатель продолжает указывать на себя

Я полный новичок, поэтому надеюсь, что вы понимаете мой стиль программирования. Я пытаюсь создать программу на C++, которая решает проблему 8 головоломок с использованием алгоритма поиска A * с формулой расстояния Манхэттена в качестве ее эвристического значения. Я завершил настройку, и это два класса, которые я создал.

class State {
public:
  int gValue;
  int hValue;
  int fValue;
  int current[3][3];
  Pair zeroPos;
  State* previous;

  State();
  State(int[][3], State*);

  bool operator<(const State& s) const {
    return this->fValue < s.fValue;
  }

  Pair findIndex(int);
  bool updateZeroPos();
  void calculateHValue(int[][3]);
  void calculateFValue();
  void getNeighbors(int, Pair[4]);
  void createArrayCopy(int[][3]);
  void displayState();
};
class SearchAlgorithm {
public:
  vector<State> openList;
  vector<State> closeList;
  int goalState[3][3];

  SearchAlgorithm();
  SearchAlgorithm(int[][3], int[][3]);

  vector<State> createNextStates(State);
  void startSearch();
  int isInList(int[][3], int);
  bool equal(int[][3], int[][3]);
};

Все начинается с функции startSearch () в классе SearchAlgorithm. Одно из требований этой проблемы - убедиться, что предыдущее состояние не совпадает со следующим, чтобы оно не перемещалось туда и обратно в одном и том же положении. Для этого я планирую передать экземпляр State в функции createNextStates (). При запуске программы никаких проблем не возникло. Но когда он доходит до создания следующих состояний для второго шага, возникает некоторая ошибка, которую я не понимаю. Состояние, полученное функцией createNextStates, не является состоянием, которое я передал при его вызове. Предположительно, он правильно вызывал предыдущее состояние, но когда он входит в функцию createNextStates, State * previous продолжает указывать на себя.

Это мой фрагмент моей функции startSearch

void SearchAlgorithm::startSearch() {
  while(!openList.empty()) {
    // Get lowest fValue state then pop
    State currentState = this->openList.back();
    this->openList.pop_back();
    if (equal(currentState.current, goalState)) {
      currentState.displayState();
      break;
    }

    cout << currentState.fValue << ":" << currentState.gValue << ":" << currentState.hValue << endl;
    cout << openList.size() << " NEXT" << endl;
    
    vector<State> neighbors;
    neighbors = this->createNextStates(currentState);

И это для моей функции createNextStates:

vector<State> SearchAlgorithm::createNextStates(State stte) {
  Pair neighbors[4];
  stte.getNeighbors(0, neighbors);
  vector<State> stateNeighbors;

  for(int i=0; i<4; i++) {
    if (neighbors[i].first != -1 && neighbors[i].second != -1) {
        int newArray[3][3];
        stte.createArrayCopy(newArray);  
        State newState(newArray, &stte);

        newState.current[newState.zeroPos.first][newState.zeroPos.second] = stte.current[neighbors[i].first][neighbors[i].second];
        newState.current[neighbors[i].first][neighbors[i].second] = 0;
        newState.updateZeroPos();

        if (stte.previous == nullptr || !equal(newState.current, stte.previous->current)) {
            stateNeighbors.push_back(newState);
        }
    }
  

}

  return stateNeighbors;
}

Я попытался отладить код с помощью функции отладчика кода VS. Перед вызовом функции это то, что хранится в переменной currentState.

(currentState).previous: 0x00007ffeefbff350
((State *)0x00007ffeefbff350)->previous: 0x0000000000000000

При входе в функцию и передаче currentState в качестве параметра происходит следующее:

(stte).previous: 0x00007ffeefbff350
((State *)0x00007ffeefbff350)->previous: 0x00007ffeefbff350

И это предыдущее продолжается. Он продолжает указывать на себя.

Буду признателен за вашу помощь в этом. Я попытался поискать в другом месте и, похоже, не нашел решения этой ошибки. Заранее спасибо. Простите за длинный пост. И снова извините за не элегантный стиль кодирования. Все еще новичок.

Я делаю предположение: вы никогда не использовали отладчик, верно? Если это так, добавьте распечатки начала и конца функции каждый, чтобы вы знали, какие значения вы хотите ввести в функцию и какие они выводятся.

Ted Lyngmo 10.04.2021 06:29

Что вы заметили при пошаговом выполнении кода построчно в отладчике? Были ли какие-то неожиданные смены значений переменных, пропущенные условные переходы?

πάντα ῥεῖ 10.04.2021 06:30

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

Boombastic 10.04.2021 06:32

Хорошо, я ухожу. Я не могу читать картинки.

Ted Lyngmo 10.04.2021 06:33

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

Boombastic 10.04.2021 06:37

@Boombastic По какой-то причине вы пока не можете публиковать изображения. Однако вы также можете предоставить эту информацию в виде правильно отформатированного текста.

πάντα ῥεῖ 10.04.2021 06:38

Я понимаю. Очень жаль. Я не привык размещать сообщения в переполнении стека. Я изменю изображения и скопирую вставку.

Boombastic 10.04.2021 06:40

Изменил изображения уже и напечатал его вместо этого.

Boombastic 10.04.2021 06:50
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
8
32
0

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