Frage

Rufen Sie STD :: Iterator Iterator auf? Wie ich unten 5. aus der letzten Zeile getan habe ..? Wenn ja, was ist besser, um alle Elemente vom Set zu löschen

class classA
{
public:
    classA(){};
    ~classA(){};
};
struct structB
{
};

typedef std::set <classA*, structB> SETTYPE;        
typedef std::map <int, SETTYPE>MAPTYPE;

int __cdecl wmain (int argc, wchar_t* pArgs[])
{
    MAPTYPE mapObj; 
    /*
      ...
      ..   Some Operation Here
      ...
      */
    for (MAPTYPE::iterator itr1=mapObj.begin(); itr1!=mapObj.end(); itr1++) 
    {       
        SETTYPE li=(*itr1).second;
        for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();itr2++) 
        {
            classA *lt=(classA*)(*itr2);
            li.erase(itr2); 
            delete lt; // Does it invalidate Iterator ?
        }
    }
}
War es hilfreich?

Lösung

Da Sie anscheinend jedes Element des Sets löschen, könnten Sie es einfach tun:

    for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();itr2++) 
    {
            classA *lt=(classA*)(*itr2);
            delete lt;
    }
    li.clear(); // clear the elements

Andere Tipps

Aus Standard 23.1.2

Die Einfügungsmitglieder beeinflussen nicht die Gültigkeit von Iteratoren und Verweise auf den Container, und die Löschelemente müssen nur Iteratoren und Verweise auf die gelöschten Elemente ungültig machen.

BEARBEITEN

In Ihrem Fall wird ITR2 nach dem Löschen ungültig gemacht, so dass das Inkrementieren undefiniertes Verhalten verursacht. In diesem Fall können Sie Reko_t Ratschläge befolgen. Im Allgemeinen können Sie dies ausprobieren:

for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();) 
{
    classA *lt=(classA*)(*itr2);
    li.erase(itr2++); 
    delete lt;
}

das wird Iterator erhöht Vor Das Entfernen des vorherigen Wertes vom SET ist.
Übrigens. IRR2 wird nicht ungültig durch delete lt;, sondern durch li.erase(itr2);

Das Löschen ist in Ordnung.

Das Problem ist, dass Sie löschen - und damit ungültig machen - itr2, aber benutze es für die Schleifen -Iteration.

IAW nach dem ersten Löschen, die ++itr2 hat undefinierte Ergebnisse.

Das Muster, das ich in dieser Situation verwende, lautet:

while(itr2 != end())
{
   iterator toDelete = itr2;
   ++itr2;   // increment before erasing!
   container.erase(toDelete);
}

Einige nicht standardmäßige STL haben die Rückgabe des nächsten Iterators, sodass Sie dies tun können:

while(itr2 != end())
   itr2 = container.erase();

Das ist jedoch nicht tragbar.


das set<A*,B> ist Seltsam, aber in einem Standard -Impl, wäre B der Komparator.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top