【问题标题】:map/set iterator is not dereferencable C++ mapmap/set 迭代器不是可解引用的 C++ 映射
【发布时间】:2013-06-19 09:32:44
【问题描述】:

请看一下我的代码。

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

它将命令注册到一个映射中,该映射包含其命令名称和指向其类的指针。 这编译没有问题,但是当我输入命令时,它会因“map/set iterator not dereferencable”而崩溃。我是地图新手(几分钟),所以请帮忙。

编辑。好的,我发现问题不在 main... 这是 Program 类的代码(其中一些)

    void Program::addCommand(std::string command1, Command* obj) {
    m_allCommands[command1] = obj;
}

std::map<std::string, Command*> Program::getCommands () {
    return m_allCommands;
}

我认为问题出在这里,因为我在 main 中注册命令后,我无法找到任何命令的名称(同样的问题)

【问题讨论】:

  • 尝试在it = allcommand-&gt;getCommands().find(parsedinput[0]);这一行之后检查it
  • 同样的问题,当我删除该行之后的所有内容并尝试计算它时->首先是字符串
  • 我的意思是,尝试检查it是否与allcommand-&gt;getCommands().end()不同,即检查命令是否存在。也尝试使用调试器并找到引发错误的行。
  • 小心你的delete obj;,在当前代码中它会在地图中留下一个悬空指针。

标签: c++ map stl iterator


【解决方案1】:
std::map<std::string, Command*> Program::getCommands () {
    return m_allCommands;
}

返回m_allcommands 映射的副本。所以当你这样做时:

it = allcommand->getCommands().find(parsedinput[0]);

您会在allcommand-&gt;getCommands() 返回的临时对象上获得一个迭代器,该迭代器在分配完成时会被销毁。因此它什么也没有。

getCommands() 更改为:

std::map<std::string, Command*>& Program::getCommands () {
    return m_allCommands;
}

甚至更好:

const std::map<std::string, Command*>& Program::getCommands () const {
    return m_allCommands;
}

【讨论】:

  • 好人,这很有效,非常感谢(仍然不敢相信我错过了)无论如何这又带来了另一个问题。好的,当我输入命令时,它可以工作,但是当我输入第二个命令时它崩溃(不知道在这里问是否是个好主意)
  • 不要删除obj。如果您两次输入相同的命令,您的命令对象需要在您的内部映射中仍然存在。删除命令对象的地方在Program::~Program()
【解决方案2】:

致电find() 后,您需要检查是否

if(it == allcommand->getCommands().end()) {
   //Not Found
} else {
   obj = it->second;
   obj->start(parsedinput);
}

【讨论】:

  • 请再看一遍相同的代码(我添加了一些信息)
  • 是第一次发生还是第二次发生,正如上面有人所说,您不应该在使用命令后调用delete obj,因为那样该命令将永远消失。您没有发布足够的代码。如果您使用调试器,它应该能够将您指向发生无效取消引用的行
  • 第一次,所以没注意。 OK 调试器显示问题出在 if(it == allcommand->getCommands().end()) {
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 2011-07-31
  • 2013-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多