Почему моя программа возвращает мусор при доступе к значению указателя? - PullRequest
0 голосов
/ 11 декабря 2018

Когда запускается приведенный ниже код, я получаю вывод мусора.Я отладил его достаточно, чтобы выяснить, возникает ли ошибка при попытке доступа к hobbies[i]->hobby.Любая помощь будет оценена.Я пытался выяснить, что происходит часами.

int Graph::addUserToHobby(std::string hobby, std::string id){
  int key = ((int)hobby[0] + (int)hobby[1])%HASHMAP_SIZE;
  int collisions = 0;
  while(hobbies[key] != NULL && hobbies[key]->hobby.compare(hobby) != 0 ){
    key++;
    collisions++;
    if(key >= HASHMAP_SIZE){
      key = 0;
    }
  }

  if(hobbies[key] == NULL){
    hobbylist hob;
    hob.hobby = hobby;
    hob.list.push_back(findVertex(id));
    hobbies[key] = &hob;
  }
  else{
    hobbies[key]->list.push_back(findVertex(id));
  }
  return collisions;

}

void Graph::displayHobbies(){

  for(int i=0; i<HASHMAP_SIZE; i++){
    if(hobbies[i] != NULL){
      cout << hobbies[i]->hobby << ": ";
      for(unsigned int j=0; j<hobbies[i]->list.size()-1; j++){
        cout << hobbies[i]->list[j]->name << ", ";
      }
      cout <<  hobbies[i]->list[hobbies[i]->list.size()-1]->name << endl;
    }
  }
}

Ответы [ 3 ]

0 голосов
/ 11 декабря 2018

Сосредоточьте ваше внимание на этой части кода:

if(hobbies[key] == NULL) {
  hobbylist hob;
  ...        
  hobbies[key] = &hob;
}

Когда hob выйдет из области видимости (в конце тела этого оператора if), hobbies[key] будет ссылаться на то, что небольше не существует.

Позже в вашей программе, как вы правильно заметили, когда вы делаете cout << hobbies[i]->hobby;, вы будете запрашивать hobby для чего-то, что вышло из области видимости, что вызывает Неопределенное поведение (UB).


Некоторые возможные решения:

  1. Использование std::map вместо массива указателейВы используете сейчас.Контейнер автоматически позаботится об управлении памятью.(Рекомендуется)
  2. Используйте умные указатели (например, std::unique_ptr) вместо необработанных указателей.Подробнее читайте в Что такое интеллектуальный указатель и когда его следует использовать?
  3. Динамически выделяйте hob, так что его время жизни увеличивается (это означает, что когда тело этого оператора if завершается, hob срок жизни не закончится).Этот подход требует, чтобы вы отвечали за управление памятью (вы должны отменить выделение каждого фрагмента памяти, который вы динамически выделяли ранее (вызывайте delete столько раз, сколько вы вызывали new)).
0 голосов
/ 11 декабря 2018

Ваша проблема в том, что вы заполняете значение hobbies указателями на объекты , расположенные в стеке .

Эти объекты впоследствии будут уничтожены.Возможно, вы хотели выделить их в кучу с new?

hobbylist* hob = new hobbylist;
...
hobbies[key] = hob 
0 голосов
/ 11 декабря 2018

В этой части:

if(hobbies[key] == NULL){
  hobbylist hob;
  /* ... */
  hobbies[key] = &hob;
}

hob размещается в стеке и удаляется после блока if.Так что указатель у вас в hobbies[key] болтается.Вы можете отлавливать подобные ошибки с помощью valgrind.

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