0

次の std::map が定義されています。

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

上記で定義された Map インスタンスの値に保持されているベクター内の特定の EndPointAddr* ポインターを削除することを目的とする関数を以下に示しました。次のシナリオが実現した後、gdb で SEGABORT を取得しています。

  1. 複数のアイテムをマップに追加する
  2. 以下の機能を使用して、項目を 1 つずつ削除します。
  3. それらの削除されたアイテムを再度追加します(それらのいくつか)
  4. 1つのアイテムを削除==>この時点で、GDBで次のメッセージを含むsigabortを取得します。

    * glibc が検出されました * /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/build_output/ServiceRegistrar: 二重解放または破損 (fasttop): 0x00007ffff0002e10 *

GDBバックトレースは下部にあります...

QUESTION 以下の削除機能で、具体的に何が間違っていると思いますか? この「ダブル フリーまたは破損」エラーが発生するのはなぜですか? 最初に削除するアイテムを見つけ、次にそれをベクトルから削除し、最後に割り当てを解除する削除機能に何が欠けていると思いますか。

除去機能

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
4

1 に答える 1

1

有効かどうかを確認せずに found を使用しているようです。値を見つけられずに がfind_if返された場合serviceList->end()、逆参照していることになりますserviceList->end()

この逆参照された値を格納している変数は、後で削除しようとしたときに問題を引き起こす変数です。実際に一致する値を見つけていると確信していますか?

于 2013-06-18T19:01:55.013 に答える