Reputation: 5090
Please, have a look at my code.
int main () {
Program* allcommand = new Program;
allcommand->addCommand("add", new Add);
allcommand->addCommand("convert", new Convert);
allcommand->addCommand("exit", new Exit);
allcommand->addCommand("help", new Help);
allcommand->addCommand("show", new Show);
allcommand->addCommand("modify", new Modify);
std::string input;
Command* obj;
while (true) {
std::cout << "\nCommand >> ";
std::getline(std::cin, input);
std::map<std::string, Command*> :: iterator it;
std::vector<std::string> parsedinput = allcommand->parse(input);
it = allcommand->getCommands().find(parsedinput[0]);
obj = it->second;
obj->start(parsedinput);
delete obj;
}
return 0;
}
It registers commands to a map which holds its command name and pointer to its class. This compiles without problems but when I enter a command, it crashes with "map/set iterator not dereferencable". I am new to maps (few minutes) so please help.
EDIT. Ok I found that the problem is not in main... Here is code of Program class (some of it)
void Program::addCommand(std::string command1, Command* obj) {
m_allCommands[command1] = obj;
}
std::map<std::string, Command*> Program::getCommands () {
return m_allCommands;
}
I think the problem is here, because after i register commands in main, I cannot cout the name of any command (same problem)
Upvotes: 1
Views: 3940
Reputation: 2237
std::map<std::string, Command*> Program::getCommands () {
return m_allCommands;
}
returns a copy of the m_allcommands
map. So when you do:
it = allcommand->getCommands().find(parsedinput[0]);
You get an iterator on the temporary object returned by allcommand->getCommands()
that gets destroyed when the assignment is done. Therefore it points to nothing.
Change getCommands()
to:
std::map<std::string, Command*>& Program::getCommands () {
return m_allCommands;
}
or even better:
const std::map<std::string, Command*>& Program::getCommands () const {
return m_allCommands;
}
Upvotes: 3
Reputation: 7775
After a call to find()
you need to check if
if(it == allcommand->getCommands().end()) {
//Not Found
} else {
obj = it->second;
obj->start(parsedinput);
}
Upvotes: 2