【问题标题】:std::map::iterator crashes program on incrementstd::map::iterator 在增量时使程序崩溃
【发布时间】:2009-10-19 04:56:35
【问题描述】:

这是什么原因造成的?

这是堆栈跟踪:

#0  0x0645c0f5 in std::_Rb_tree_increment (__x=0x83ee5b0)
    at ../../../../libstdc++-v3/src/tree.cc:69
#1  0x0805409a in std::_Rb_tree_iterator<std::pair<std::string const, Widget*> >::operator++ (
    this=0xbffff144)
    at /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/stl_tree.h:192
#2  0x08053d32 in Generic::StartLayout (this=0x8287d68) at Generic.cpp:195
#3  0x0804f6e1 in LCDControl::ConfigSetup (this=0xbffff26c) at LCDControl.cpp:91
#4  0x0804ed7c in LCDControl::Start (this=0xbffff26c, argc=1, argv=0xbffff404) at LCDControl.cpp:21
#5  0x08050964 in main (argc=1, argv=0xbffff404) at Main.cpp:11

这是代码:

    for(std::map<std::string,Widget *>::iterator w = widgets_.begin();
        w != widgets_.end(); w++){
        if( w->second->GetType() & WIDGET_TYPE_BAR) {
            w->second->SetupChars();
        }
        w->second->Start();

    }

编辑:下一个问题是相关的,所以我不会提出一个全新的问题。我会保持原样接受答案。我只需要知道一些事情。在函数调用之后,我有两个迭代器,一个是主迭代器,一个在主迭代器内。它们都与同一张地图有关。好吧,里面的那个都坏了,主循环停止迭代。

这是代码。

这是开始布局:

void Generic::StartLayout() {
    Error("StartLayout: %s", key.c_str());
    for(std::map<std::string,Widget *>::iterator w = widgets_.begin();
        w != widgets_.end(); w++){
        Error("Starting widget %s", w->first.c_str());
        if( w->second->GetType() & WIDGET_TYPE_SPECIAL) {
            w->second->SetupChars();
        }

        w->second->Start();
    }
}

这里是 SetupChars():

void WidgetGif::SetupChars() {
    Error("SetupChars <%s> <%s>", name_.c_str(), widget_base_.c_str());
    Error("Size of widgets: %d", visitor_->Widgets().size());
    std::map<std::string, Widget *> widgets = visitor_->Widgets();
    for(std::map<std::string, Widget *>::iterator ii=visitor_->Widgets().begin();
        ii != visitor_->Widgets().end(); ii++) {
        Error("<%s> Widget base %s == %s", ii->first.c_str(), ii->second->GetWidgetBase().c_str(), widget_base_.c_str());
        if(ii->second->GetWidgetBase() == widget_base_ &&
            ((WidgetGif *)ii->second)->HasChars()) {
            Error("Using chars from %s", ii->first.c_str());
            for(unsigned int i = 0; i < rows_ * cols_; i++ ) {
                if(i >= visitor_->GetLCDText()->CHARS) {
                    Error("1) GIF too large: %s, %d", name_.c_str(), visitor_->GetLCDText()->CHARS);
                    if(update_) delete update_;
                    update_ = new Property(visitor_, section_, "", new Json::Value("-1"));
                    return;
                }
                    ch_[i] = ((WidgetGif *)widgets[ii->first])->GetChars()[i];
            }
            hasChars_ = true;
            return;
        }
    }
// It goes on, but I snipped it here.
}

这就是发生的事情:

StartLayout: display_qt
Starting widget widget_gif_american_flag:layout_american_flag:0
SetupChars <widget_gif_american_flag:layout_american_flag:0> <layout_american_flag>
Size of widgets: 5
<widget_gif_american_flag:layout_american_flag:1> Widget base layout_american_flag == layout_american_flag
<widget_gif_american_flag:layout_american_flag:4> Widget base layout_american_flag == layout_american_flag
<(n
(n
��S> Widget base ГS == layout_american_flag
^C

上次编辑:我想通了。我只需要新迭代器的原始地图副本。

【问题讨论】:

  • sn-p 代码来自哪个函数? Generic::StartLayout()?
  • @sth:哦,对不起。应该离开那个。是的,你是对的。

标签: c++ map std increment


【解决方案1】:

这可能有很多原因。一方面,可能是 GetType 或 SetupChars 或 Start 做了一些导致你的地图改变的事情——这会使当前的迭代器无效(注意在地图上使用operator[],即使只是为了读取值, 在技术上是一个变异操作,并且在启用迭代器调试时可能导致崩溃!)。或者,您的地图可能会被之前执行的某些代码在内存中损坏,例如因为缓冲区溢出覆盖了地图树的一部分。

【讨论】:

    【解决方案2】:

    您不得在您的任何方法GetType、SetupChars 或Start 中修改widgets_。这很可能是您的问题。

    如果您必须修改widgets_,那么无论何时进行此类更改,您都需要重新启动迭代器。为避免重复更改,您可以在循环外使用简单的标记字典,或 Widget 类的标记成员。

    【讨论】:

    • 等等,什么?当然-&gt; 是标准的,任何迭代器都提供重载运算符-&gt; - 这是特征Iterator 要求的一部分!参见 ISO C++ 24.1.1[lib.input.iterators],表 72“输入迭代器要求”,定义如下:“a->m; pre: (*a).m 是明确定义的。等价于 (*a ).m"。
    • 你们 C++ 年轻人已经完成了。当我编写 C++ 时,我们不得不取消引用我们的迭代器。去上班的路是上坡路,双向的! :-)
    猜你喜欢
    • 2015-10-25
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    相关资源
    最近更新 更多