2013-05-22 12 views
0

我的二進制文件崩潰了。在運行核心轉儲,我發現:大規模從STL向量中刪除導致我的二進制崩潰

#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); 
     } 
+1

你可以發佈代碼嗎? – hmjd

+0

@hmjd你走了。 – Chani

+0

*真實*內存損壞可能發生在此操作附近。在valgrind下運行你的程序,並修復它報告的第一個問題。重複,直到它不抱怨。 – zwol

回答

2

std::vector::erase()

迭代器和被擦除的元件和將它們與所述容器的所述端部之間的元素的引用被無效。前端迭代器也失效。

因此如果erase()被調用,下一次增加時orderbkIterator將無效。改變回路的結構erase()返回已刪除的迭代器之後的下一個迭代器,這意味着如果一個erase()沒有發生不僅增加:

for (orderbkIterator = vOrderBook.begin(); orderbkIterator != vOrderBook.end();) 
{ 
    if (...) 
    { 
     orderbkIterator = vOrderBook.erase(orderbkIterator); 
    } 
    else 
    { 
     ++orderbkIterator; 
    } 
} 
1

我敢肯定,

vOrderBook.erase(orderbkIterator); 

將無效迭代器。繼續增加它將導致未定義的結果。

+0

是的,你是對的,謝謝 – Chani

0

刪除擦除成語會阻止許多與無效迭代器的陷阱。

Rewritting使用這種風格看起來像下面的循環:

vOrderBook.erase(
    std::remove_if(vOrderBook.begin(), vOrderBook.end(), <unary-predicate>), 
    vOrderBook.end()); 

一元謂詞可能是lambda或仿函數。