首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Vector.erase中的SIGSEGV

Vector.erase中的SIGSEGV
EN

Stack Overflow用户
提问于 2015-12-31 11:50:55
回答 2查看 1K关注 0票数 0

当我擦除向量中的一个元素时,我得到了一个奇怪的分割错误。这是代码:

代码语言:javascript
复制
int i = 0;
    cout << "SIZE: " << OrderList::sellOrders.size();
    for(vector<Order>::iterator it = OrderList::sellOrders.begin(); it != OrderList::sellOrders.end(); it++, i++)
    {
        if(OrderList::sellOrders[i].pThis->usesWamp() == false)
        {
            cout << "Erase element " << i << endl;
            OrderList::sellOrders.erase(it);
        }
    }

产出如下:

代码语言:javascript
复制
SIZE: 44
Erase element 0
Erase element 2
Erase element 3
Erase element 4
Erase element 5
Erase element 6
Erase element 7
Erase element 8
Erase element 9
Erase element 10
Erase element 11
Erase element 12
Erase element 13
Erase element 14
Erase element 15
Erase element 16
Erase element 17
Erase element 18
Erase element 19
Erase element 20
Erase element 21
Erase element 22
Erase element 23

Program received signal SIGSEGV, Segmentation fault.
__memmove_ssse3_back () at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1548
1548    ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S: No such file or directory.
(gdb)
(gdb) where
#0  __memmove_ssse3_back ()
    at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1548
#1  0x0000000000485d48 in std::__copy_move<true, true, std::random_access_iterator_tag>::__copy_m<Order> (__first=0x7fffe400e4a0, __last=0x7fffe400e470,
    __result=0x7fffe400e488) at /usr/include/c++/4.8/bits/stl_algobase.h:372
#2  0x00000000004807c4 in std::__copy_move_a<true, Order*, Order*> (
    __first=0x7fffe400e4a0, __last=0x7fffe400e470, __result=0x7fffe400e488)
    at /usr/include/c++/4.8/bits/stl_algobase.h:390
#3  0x000000000047879f in std::__copy_move_a2<true, __gnu_cxx::__normal_iterator<Order*, std::vector<Order, std::allocator<Order> > >, __gnu_cxx::__normal_iterator<Order*, std::vector<Order, std::allocator<Order> > > > (__first=...,
    __last=..., __result=...) at /usr/include/c++/4.8/bits/stl_algobase.h:428
#4  0x000000000046f9d3 in std::move<__gnu_cxx::__normal_iterator<Order*, std::vector<Order, std::allocator<Order> > >, __gnu_cxx::__normal_iterator<Order*, std::vector<Order, std::allocator<Order> > > > (__first=..., __last=...,
    __result=...) at /usr/include/c++/4.8/bits/stl_algobase.h:492
#5  0x0000000000467754 in std::vector<Order, std::allocator<Order> >::erase (
    this=0x6c7c10 <OrderList::sellOrders>, __position=...)
    at /usr/include/c++/4.8/bits/vector.tcc:138
#6  0x0000000000421320 in OrderList::flush () at ../Bether/OrderList.h:339
#7  0x000000000044b12a in main () at ../Bether/main.cpp:354

因此,您可以看到向量有44个元素(SIZE: 44),但是当元素23被删除时会失败。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-31 12:01:19

std::vector::erase()使迭代器无效,这意味着它是未定义的行为,在此之后取消引用(*it)或增量它(++it)。

一个好的和通常的范例是将std::remove_if()组合起来,将要删除的项移动到容器的后面,以便std::vector::erase()实际删除它们:

代码语言:javascript
复制
std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6 };
v.erase( std::remove_if(v.begin(), v.end(), [](int n){ return n%2==0; }), v.end() );
// v is { 1, 3, 5 }
票数 6
EN

Stack Overflow用户

发布于 2015-12-31 11:54:45

erase函数使指向擦除位置的迭代器和引用无效。

如果您真的想要擦除它们,您可以更改循环以减少顺序迭代,这应该没有问题,因为您使用的向量可以很容易地允许双向访问。这样,只有对已经检查过的地点的引用才会失效。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34546115

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档