简体   繁体   中英

Why does my program return garbage when accessing the value of a pointer?

When the below code is run, I get garbage output. I have debugged it enough to figure out the error comes when I try to access hobbies[i]->hobby . Any help would be appreciated. I have been trying to figure out what is going on for hours.

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;
    }
  }
}

Focus your attention in that part of the code:

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

When hob gets out of scope (at the end of that if-statement's body), hobbies[key] will reference something that doesn't exist any more.

Later on in your program, as you correctly noticed, when you do cout << hobbies[i]->hobby; , you will request for hobby on something that has gone out of scope, which invokes Undefined Behavior (UB).


Some possible solutions:

  1. Use an std::map , instead of the array of pointers you use now. The container will automatically take care of the memory management for you. (Recommended)
  2. Use smart pointers (eg std::unique_ptr ), instead of raw pointers. Read more in What is a smart pointer and when should I use one?
  3. Dynamically allocate hob , so that its lifetime is extended (that means that when that if-statement's body terminates, hob 's lifetime won't terminate). This approach requires you to be responsible for the memory management (you have to de-allocate every piece of memory that you dynamically allocated before (call delete as many times as you called new )).

In this part:

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

hob is allocated on the stack and deleted after the if block. So the pointer you have in hobbies[key] is dangling. You can catch these sort of errors with valgrind.

Your issue is that you are populating your hobbies value with pointers to objects allocated on the stack .

These objects will have subsequently been destroyed. Perhaps you were meaning to allocate them on the heap with new ?

hobbylist* hob = new hobbylist;
...
hobbies[key] = hob 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM