std :: remove_if / find_if:双重免费或损坏

时间:2013-06-18 18:40:12

标签: c++ c++11 stdvector memory-management

我定义了以下std :: map:

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

我有下面指出的函数,其目的是删除向量中的特定EndPointAddr *指针,该指针保存在上面定义的Map实例的值中。在以下场景实现后,我在gdb中获得了一个SEGABORT:

  1. 向地图添加多个项目
  2. 逐个使用以下功能删除项目。
  3. 再次添加这些已删除的项目(其中一些)
  4. 删除一项==&gt;在这一点上,我在GDB中获得了一个sigabort,其中包含以下消息:

    *检测到glibc * / home / holb / DESIGN / ECLB_CP / REPs / V2 / eclb_cp / build_output / ServiceRegistrar:double free或corruption(fasttop):0x00007ffff0002e10 *

  5. GDB返回跟踪位于底部...

    问题 你觉得下面这个删除功能有什么特别之处?为什么我得到这个&#34;双重免费或腐败&#34;错误?您认为我在删除功能中缺少什么,我首先找到要删除的项目,然后将其从向量中删除,最后解除分配。

    删除功能

    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 BackTrace

    (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
    

1 个答案:

答案 0 :(得分:0)

您似乎在使用找不到它而不检查它是否有效。如果您未能找到值且find_if返回serviceList->end(),则您将取消引用serviceList->end()

您正在存储此解除引用值的变量是在您尝试删除它时导致您遇到麻烦的变量。你确定你真的找到了匹配的值吗?