0

I'm trying to determine what's going wrong with my code, and I have absolutely no idea what the problem is. I have an iterator that is returning the incorrect values for the object in a vector, even though printing that object in GDB shows the correct fields. The code inside the loop is not relevant for this particular issue. The three objects and functions I use in the below loop are

class User{
  string password;
  string username;

  string getName() {return username}
  string getPass() {return password}
};

class Room{
  vector<User> users;
  vector<Message> messages;
  string name;

  vector<User> getUsers() {return users}
  vector<Message> getMessages() {return messages}
  string getName() {return name}
};

class Message{
  User sender;
  string message;

  User getSender() {return sender}
  string getMessage() {return message}
};

The code in my loop is

vector<Room>::iterator roomIt;
vector<Message>::iterator messIt;

for(roomIt = rooms.begin(); roomIt < rooms.end(); roomIt++) {
  for (messIt = roomIt->getMessages().begin(); messIt < roomIt->getMessages().end(); messIt++) {
    .........
  }
}

In gdb, when I use print roomIt->getMessages().begin() I get

{sender = {password = "robin", username = "batman"}, message = "hello"}

However, when I use print messIt or print *messIt I get

{sender = {password = "batman", username = "hello"}, message = "robin"}

What could be causing this discrepancy? I'm completely lost as I can't see how printing the object is giving the correct output while setting messIt reference equal to that object alters the values.

Stephen Burns
  • 162
  • 2
  • 17
  • Your iterator is dangling. I think there's a duplicate somewhere... – Justin Apr 11 '18 at 18:28
  • 2
    Trying to find a dupe. The issue is your getters return by value instead of by reference – NathanOliver Apr 11 '18 at 18:28
  • Possible duplicate: https://stackoverflow.com/questions/23311165/iterator-got-by-applying-begin-on-getter-method-doesnt-allow-to-access-to-fir – NathanOliver Apr 11 '18 at 18:30
  • You have the same issue with your previous question [here](https://stackoverflow.com/questions/49762949/c-vectorerase-with-class-object-iterator-not-erasing-vector-member). Do you understand what the implications are of returning a copy of an object and returning a reference to the existing object? As I stated in the comments for that question, you are lucky your program didn't just crash due to using invalid iterators. – PaulMcKenzie Apr 11 '18 at 18:36
  • @PaulMcKenzie would a valid fix be changing the function to `*vector getMessages() {Message * theseMessages = &messages; return *theseMessages;} – Stephen Burns Apr 11 '18 at 18:45
  • Change the return type to return a reference. Seems as if you're still not quite understanding why you are getting the issue. – PaulMcKenzie Apr 11 '18 at 18:47
  • @PaulMcKenzie I believe I get what you are saying, but I don't believe I understand the syntax. I think I need to create a pointer by calling that function and, rather than return a copy, just return the address. vector& getMessages() {return messages;} Would this function? – Stephen Burns Apr 11 '18 at 18:55
  • There is no need for a pointer. [See this answer](https://stackoverflow.com/questions/30041907/can-i-use-nested-loops-with-vectors-in-cpp/30042185#30042185), as it describes exactly what the issue is with your code and the fix. – PaulMcKenzie Apr 11 '18 at 18:56

0 Answers0