【问题标题】:Segmentation faults in deque of user-defined pointers用户定义指针的双端队列中的分段错误
【发布时间】:2012-12-14 14:27:10
【问题描述】:

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

编辑: 这是我的代码的 sn-p:

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

【问题讨论】:

  • 迭代器可能无效?
  • 向我们展示实际代码。

标签: c++ segmentation-fault deque


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    这是我的earlier answer to a question about heap corruption 讨论此类工具,我的list of reasons you might want to overload operator new and delete 也有另一个工具列表。 (无耻的自我推销,在这里,但我认为这些都是很好的列表!)


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

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

    【讨论】:

      猜你喜欢
      • 2013-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-25
      • 1970-01-01
      相关资源
      最近更新 更多