0

我有一个deque<rect*> rectswhererect是用户定义的类。当我尝试进入它时,我遇到insertrect*分段错误。gdb将问题追溯到__memmove_sse3()我调用rects.insert(it,new rect([constructor parameters])); where itis a时调用的函数deque<rect*>::iterator。什么可能导致此错误?

编辑:这是我的代码片段:

for(deque<rect*>::iterator it=rects.begin();it!=rects.end();++it)
        {
            rect r=*r1;
            rect r2=*(*it);
            if(!r2.there)
                continue;
            if(r.down>r2.up || r.up<r2.down || r.right<r2.left || r.left>r2.right)
                continue;
            if(r.left>r2.left)
                rects.insert(it,new rect(r2.left,r2.down,r.left,r2.up,r2.color));
            if(r.right<r2.right)
                rects.insert(it,new rect(r.right,r2.down,r2.right,r2.up,r2.color));
            if(r.up<r2.up)
                rects.insert(it,new rect(max(r.left,r2.left),r.up,min(r.right,r2.right),r2.up,r2.color));
            if(r.down>r2.down)
                rects.insert(it,new rect(max(r.left,r2.left),r2.down,min(r.right,r2.right),r.down,r2.color));
            r2.there=false;
        }
4

2 回答 2

2

问题是您插入的项目std::deque会使您在for循环中递增的迭代器无效:

标准(n3485 草案)在 §23.3.3.4/1(强调我的)中说,

效果:双端队列中间的插入使所有迭代器和对双端队列元素的引用无效。在双端队列的任何一端插入都会使双端队列的所有迭代器无效,但不会影响对双端队列元素的引用的有效性。

于 2012-12-29T18:21:21.183 回答
1

段错误可以来自任意数量的来源,并且并不总是立即显现。您可能会溢出数组,以无效的方式使用 stl 容器,等等 - 当您损坏您不拥有的可能用于分配记帐的内存区域时,它可以进行未来的分配,释放,移动或任何其他间接访问都会失败。

拿出大炮可能有助于快速解决这个问题!如果您在将运行 valgrind 的系统上,则可以使用valgrind的 memcheck 模块,或者您可以在 Windows 上使用Application Verifier之类的东西。

您的编译器或库可能具有标准库/STL 调试功能——如果您在 IDE 中,请四处寻找可用的选项。对于 libstdc++(通常与 gcc/g++ 一起使用),您可以查看libstdc++ 调试支持选项

这是我之前对讨论此类工具的堆损坏问题的回答,我列出的您可能想要重载 operator new 和 delete 的原因还有另一个工具列表。(无耻的自我推销,在这里,但我认为这些都是相当不错的清单!)


根据您的代码,我会说您使循环迭代器无效。来自http://www.sgi.com/tech/stl/Deque.html

deque 的迭代器失效语义如下。插入(包括 push_front 和 push_back)使所有引用双端队列的迭代器无效。在双端队列中间进行擦除会使所有引用该双端队列的迭代器无效。仅当迭代器指向已擦除的元素时,在双端队列(包括 pop_front 和 pop_back)的开头或结尾进行擦除才会使迭代器无效。

于 2012-12-29T18:16:44.950 回答