分割错误,两个指针迭代地图,同时更改地图

时间:2016-07-27 08:53:20

标签: c++

我是cpp的新手,并且有一段代码可以运行:

void particleFilter::mergeFilters(double mergeBound){
    for(map<int, filter>::iterator fi = filters.begin(); fi != filters.end();){
        for(map<int, filter>::iterator ji = filters.begin(); ji != filters.end(); ){
            Rect recI = (fi -> second).getRecFilter();
            Rect recJ = (ji -> second).getRecFilter();
            double dis = (double)sqrt((double)(recI.x-recJ.x)*(recI.x-recJ.x)+(double)(recI.y-recJ.y)*(recI.y-recJ.y));
            if(dis<mergeBound && dis>1){
                double wi = (fi -> second).pi;
                double wj = (ji -> second).pi;
                cout <<"call remove function" << endl;
                if(wi<wj){
                    cout << "remove id is " << (fi->second).objectID << endl;
                    removeFilter((fi->second).objectID);
                    fi++;
                }
                else{
                    cout << "remove id is " << (ji->second).objectID << endl;
                    removeFilter((ji->second).objectID);
                    ji++;
                }
            }
            else{
                ++ji;
            }
        }
        ++fi;
    }
}

它只有两个指针来比较地图的每两个条目,但同时,它会删除地图的一些条目。 removeFilter((fi->second).objectID);函数肯定没有任何问题。

任何人都有任何想法,为什么分段错误?

3 个答案:

答案 0 :(得分:3)

您需要更改此代码:

                removeFilter((fi->second).objectID);
                fi++;

类似于:

auto tmpIt = fi;
fi++;
removeFilter((tmpIt->second).objectID);

并对等效的ji代码进行类似的更改。

这是因为即使没有其他迭代器到容器,被擦除的迭代器也会失效。因此,您正在修改无效的迭代器,这是未定义的行为。复制并递增它首先解决了这个问题。

答案 1 :(得分:1)

您不能删除由fi或ji控制的过滤器,然后尝试使用此变量(例如,作为++ fi ++ ji)

答案 2 :(得分:1)

您似乎在内循环中增加fi而不检查是否fi != filters.end()