0

オブジェクトを含むベクトルがいくつかあり、必要なオブジェクトに到達するためのネストされた一連のループがあります

if (_dir->Instance()->isDebug())
{
    Utils::LogTextWithInt("growing timers size: ", _glo->Instance()->getGrowingTimers().size());
    for (int i=0; i < _glo->Instance()->getGrowingTimers().size(); i++)
    {
         GrowingTimer _growingTimer = _glo->Instance()->getGrowingTimers().at(i);

        std::cout << "growing timer Field id and plant id: " << _growingTimer.getFieldID() << " - "
                    << _growingTimer.getPlantID() << std::endl;
    }
}

std::vector<GrowingTimer>::iterator _gtIterB = _glo->Instance()->getGrowingTimers().begin();

for (_gtIterB; _gtIterB != _glo->Instance()->getGrowingTimers().end(); ++_gtIterB)
{       
    for (std::vector<Field>::iterator _fIterB = _glo->Instance()->getFields().begin();
         _fIterB != _glo->Instance()->getFields().end(); ++_fIterB)
    {          
        if (_gtIterB->getFieldID() == _fIterB->getFieldNumber())
        {
            for (std::vector<Plant>::iterator _pIterB = _fIterB->getPlants().begin();
                 _pIterB != _fIterB->getPlants().end(); )
            {
                if (_gtIterB->getPlantID() == _pIterB->getPlantID())
                {
                    Utils::LogText("gt and plant ID's match");
                    Utils::LogTextWithInt("Plant ID after matching: ", _pIterB->getPlantID());

                    // Wiggle our plant.
                    Utils::wiggleNode(_pIterB->getPlantSprite(), 10.0f, 5.0f);

                    _pIterB->setPlantStoppedGrowing(true);

                    _gtIterB = _glo->Instance()->getGrowingTimers().erase(_gtIterB);

                    ++_pIterB;
                }
                else
                {
                   ++_pIterB;
                }

            }
        }
    }
}

出力は次のとおりです。

growing timers size:  2
growing timer Field id and plant id: 7620 - -2130819608
growing timer Field id and plant id: 7620 - -2130802800
gt field id:  7620 
gt plant id:  -2130819608
gt and plant ID's match
Plant ID after matching:  -2130819608
deleted
gt and plant ID's match
Plant ID after matching:  -2130802800
deleted
gt field id:  7620
gt plant id:  -2130802800
gt and plant ID's match
Plant ID after matching:  -2130802800

このすべての後にクラッシュしています:

0x209eff0:  addb   %ah, %gs:115(%ecx,%ebp,2)
0x209eff5:  jo     0x209f063                 ; "nitWithCondition:"
0x209eff7:  popal  
0x209eff8:  jns    0x209f048                 ; "'v'"
0x209effa:  popal  
0x209effb:  insl   
0x209effc:  incl   %esi
0x209effe:  outsl  
0x209efff:  jb     0x209f04c                 ; "ckBeforeDate:"
0x209f001:  jns    0x209f03e                 ; "Name:"
0x209f004:  jbe    0x209f067                 ; "ithCondition:"
0x209f006:  insb   
0x209f007:  jne    0x209f06e                 ; "ition:"
0x209f009:  cmpb   (%eax), %al
0x209f00b:  popl   %edi
0x209f00c:  jo     0x209f080                 ; "lSinceNow"

_gIterB基本的に、一致があり、それに基づいて行動したので、不要になった位置を削除したいと思います。このベクターは、実行中の時間指定イベントの場合、「トラッカー」として追加され続けます。これにより、タイマーが終了したときに、タイマーが何のオブジェクトであったかがわかり、次のステップを実行するためにそれに戻ることができます。

編集: GrowingTimer のベクトルには、「成長中」の fieldID と PlantID が格納されているため、それに戻ることができます。

Fields のベクトルには、ユーザーが持つすべてのフィールドが格納され、メンバーとして各 Field オブジェクトにはフィールド内の植物のベクトルがあります。1畑に8株。

ユーザーが作成する各フィールドには一意の ID があります。以下の出力は、2 つの植物を含む 1 つのフィールドがあることを示しています。

4

1 に答える 1

0
for (auto _gtIterB=grow_timers.begin(); _gtIterB!=grow_timers.end(); ++_gtIterB) {     
    ...
    _gtIterB = _glo->Instance()->getGrowingTimers().erase(_gtIterB);
    .... 
}

つまり、基本的に、ここには 2 つの問題があります。

  • _gtIterB を消去すると、次の成長タイマーの位置が割り当てられます。これは、このグロータイマーを多くの植物と比較することをスキップしたことを意味します。これは悪いことだと思いますが、おそらくクラッシュの原因ではありません。
  • _gtIterB が終了イテレータに設定されている最後の有効な growtimer であるときに _gtIterB を消去すると、for ループの次の部分に到達したときに++_gtIterB再びループが終了し、何が起こるか分からなくなります。これは絶対にダメです。

これらのいずれかがクラッシュを引き起こしているかどうかはわかりません。

しかし、これはあなたのコードの私の解釈であり、より速く、深くネストされていません: http://ideone.com/zcfnv8

于 2013-08-28T00:23:36.003 に答える