我的二进制文件正在崩溃。在运行核心转储时,我发现了以下内容:
#0 0x00a6a363 in memmove () from /lib/tls/libc.so.6
(gdb) frame 1
#1 0x083a108c in std::__copy_trivial<piola::piolaOrderBook*> (__first=0xb277f2c4, __last=0xb277f2bc, __result=0xb277f2c0)
at /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stl_algobase.h:258
258 std::memmove(__result, __first, sizeof(_Tp) * (__last - __first));
(gdb) frame 2
#2 0x083a0ad6 in std::__copy_aux2<piola::piolaOrderBook*> (__first=0xb277f2c4, __last=0xb277f2bc, __result=0xb277f2c0)
at /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stl_algobase.h:279
279 { return std::__copy_trivial(__first, __last, __result); }
(gdb) frame 3
#3 0x083a02d1 in std::__copy_ni2<piola::piolaOrderBook**, __gnu_cxx::__normal_iterator<piola::piolaOrderBook**, std::vector<piola::piolaOrderBook*, std::allocator<emapi::EmapiOrderBook*> > > > (__first=0xb277f2c4, __last=0xb277f2bc, __result=
{_M_current = 0xb277f2c0})
at /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stl_algobase.h:296
296 return _OutputIterator(std::__copy_aux2(__first, __last, __result.base(),
(gdb) frame 4
#4 0x0839f1b0 in std::__copy_ni1<__gnu_cxx::__normal_iterator<piola::piolaOrderBook**, std::vector<piola::piolaOrderBook*, std::allocator<piola::piolaOrderBook*> > >, __gnu_cxx::__normal_iterator<piola::piolaOrderBook**, std::vector<piola::piolaOrderBook*, std::allocator<piola::piolaOrderBook*> > > > (__first={_M_current = 0xb277f2c4}, __last=
{_M_current = 0xb277f2bc}, __result={_M_current = 0xb277f2c0})
at /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stl_algobase.h:317
317 return std::__copy_ni2(__first.base(), __last.base(),
(gdb) frame 5
#5 0x0839d676 in std::copy<__gnu_cxx::__normal_iterator<piola::piolaOrderBook**, std::vector<piola::piolaOrderBook*, std::allocator<piola::piolaOrderBook*> > >, __gnu_cxx::__normal_iterator<piola::piolaOrderBook**, std::vector<piola::piolaOrderBook*, std::allocator<piola::piolaOrderBook*> > > > (__first={_M_current = 0xb277f2c4}, __last={_M_current = 0xb277f2bc},
__result={_M_current = 0xb277f2c0})
at /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stl_algobase.h:358
358 return std::__copy_ni1(__first, __last, __result, __Normal());
(gdb)
大部分内容对我来说都很神秘,但是在查找memmove时,似乎代码崩溃了,因为它无法处理向量中的删除(因为从向量中删除对于大向量来说是一个非常繁重的操作)?
我说错了吗?如果是,我该如何解决这个问题(除了修复设计之外)?
代码在这里:
for (orderbkIterator = vOrderBook.begin(); orderbkIterator != vOrderBook.end(); orderbkIterator++)
{
if ( (*(*orderbkIterator)->getOrderBookId()) == *(TradableInst->getOrderBookId()) )
{
long long a = (*(*orderbkIterator)->getOrderBookId());
ADDVLOG(LOG_INFO, "Removing record (%lld) from vOrderBook", a );
vOrderBook.erase(orderbkIterator);
}
答案 0 :(得分:2)
对擦除元素及其与容器末尾之间元素的迭代器和引用无效。过去的迭代器也是无效的。
如果orderbkIterator
被调用,则下次递增时erase()
将无效。更改循环的结构,因为erase()
在删除的迭代器之后返回下一个迭代器,这意味着只有在erase()
没有发生时才会增加:
for (orderbkIterator = vOrderBook.begin(); orderbkIterator != vOrderBook.end();)
{
if (...)
{
orderbkIterator = vOrderBook.erase(orderbkIterator);
}
else
{
++orderbkIterator;
}
}
答案 1 :(得分:1)
我很确定
vOrderBook.erase(orderbkIterator);
将使迭代器无效。继续增加会导致不确定的结果。
答案 2 :(得分:0)
删除擦除习惯用法可以防止使用无效迭代器的许多陷阱。
使用这个习惯用法重写循环看起来如下:
vOrderBook.erase(
std::remove_if(vOrderBook.begin(), vOrderBook.end(), <unary-predicate>),
vOrderBook.end());
一元谓词可以是lambda或functor。