2013-06-18 67 views
0

我已經定義了以下的std ::地圖:的std ::的remove_if/find_if:雙免費或腐敗

//The map holding the list of registered services per partition key. 
std::map<SRServicePartitionKey, std::vector<EndPointAddr*>* > mServiceMap; 

我在下面指示的功能,其目的是在載體中刪除特定EndPointAddr *指針保存在上面定義的Map實例的值中。我越來越廣發行SEGABORT實現以下情形後:

  1. 由一個多個項目添加到地圖
  2. 刪除使用這個函數的一個項目。
  3. 再次添加這些已刪除的項目(其中的幾個)
  4. 刪除一個項目==>此時,我得到了GDB以下消息SIGABORT一個:

    * glibc的檢測* /家/ HOLB /設計/ ECLB_CP/REP的/ V2/eclb_cp/build_output/ServiceRegistrar:雙重釋放或腐敗(fasttop):0x00007ffff0002e10 *

GDB回溯可在底部...

問題 你認爲在下面的刪除功能中有什麼特別的東西是錯誤的?爲什麼我得到這個「雙免費或腐敗」的錯誤?您認爲我在刪除功能中缺少什麼,我首先找到要刪除的項目,然後將其從載體中移除並最終釋放它。

去除功能

bool 
ServiceRegistrar::removeService(const EndPointAddr & epAddrForRemoval) 
{ 
    bool condErased = false; 

    for(auto it = mServiceMap.begin(); it != mServiceMap.end(); ++it) 
    {  
     std::cout << "\tPartition [" 
        << (*it).first.getInstanceNo() << "," 
        << (*it).first.getContext() << "," 
        << (*it).first.getVersion() << "]:" 
        << std::endl; 

     std::vector<EndPointAddr*> * serviceList = (*it).second; 

     auto found = 
      std::find_if(serviceList->begin(), 
         serviceList->end(), 
         [epAddrForRemoval](EndPointAddr* otherEPAddr) 
         { 
          const EndPointTipcAddr & tipcAddrToRemove = epAddrForRemoval.getImmutableTipcAddress(); 
          const EndPointTipcAddr & otherTipcAddr = otherEPAddr->getImmutableTipcAddress();                       
          return (tipcAddrToRemove.compareTo(otherTipcAddr));     
         });  

    EndPointAddr * toBeDeAllocatedEP = *found; 

    auto toBeErasedEP = 
     std::remove_if(serviceList->begin(), 
         serviceList->end(), 
         [epAddrForRemoval](EndPointAddr* otherEPAddr) 
         { 
          const EndPointTipcAddr & tipcAddrToRemove = epAddrForRemoval.getImmutableTipcAddress(); 
          const EndPointTipcAddr & otherTipcAddr = otherEPAddr->getImmutableTipcAddress();                       
          return (tipcAddrToRemove.compareTo(otherTipcAddr));     
       }); 

    if(toBeErasedEP != serviceList->end()) 
    {   
     serviceList->erase(toBeErasedEP, serviceList->end());  
     condErased = true; 
    } 

    if(toBeDeAllocatedEP != 0) 
    { 
     !!!!!!!!!!!!LINE 1396 is HERE!!!!!!!!!!!!!!! 
     delete toBeDeAllocatedEP; 
    } 

    } //end of For Loop 

    return condErased; 
} 

GDB回溯

(gdb) bt 
#0 0x00007ffff7026425 in raise() from /lib/x86_64-linux-gnu/libc.so.6 
#1 0x00007ffff7029b8b in abort() from /lib/x86_64-linux-gnu/libc.so.6 
#2 0x00007ffff706439e in ??() from /lib/x86_64-linux-gnu/libc.so.6 
#3 0x00007ffff706eb96 in ??() from /lib/x86_64-linux-gnu/libc.so.6 
#4 0x00007ffff7681540 in std::basic_string<char, std::char_traits<char>,  std::allocator<char> >::~basic_string()() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
#5 0x0000000000434604 in EndPointIpAddr::~EndPointIpAddr (this=0x7ffff0002fb0, __in_chrg=<optimized out>) at /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/src/control_components/../control_api/api_util/EndPointIpAddr.hpp:28 
#6 0x0000000000434660 in EndPointAddr::~EndPointAddr (this=0x7ffff0002f90, __in_chrg=<optimized out>) at /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/src/control_components/../control_api/api_util/EndPointAddr.hpp:36 
#7 0x000000000043c97f in ServiceRegistrar::removeService (this=0x7fffffffdea0, epAddrForRemoval=...) at /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/src/control_api/ServiceRegistrar.cpp:1396 
+0

可能不相關:儘管'const&'接受'epAddrForRemoval',你正在捕獲每個lambda中的副本。如果複製成本很高,請參考它。如果不是,爲什麼不按值傳入'removeService'? – Casey

回答

0

你似乎沒有檢查它是否有效或不使用發現。如果您未能找到值,並且find_if返回serviceList->end(),那麼您將取消引用serviceList->end()

你正在存儲這個解除引用的值的變量是當你試圖刪除它時會導致你麻煩的那個變量。你確定你確實找到了匹配的值嗎?