ASten
ASten

Reputation: 814

Does QT's QList save iterators after container's modifications?

Are the iterators pointed to elements of QList still valid after there are any remove operation from QList? I need to remove some element from QList, so I store an iterators for those elements to another container and than take this saved iterators and use to remove necessary elements from QList. It looks like this:

// inside a loop for 'list'
QList<type>::iterator it = list.begin() + j;
removing.append(it);
// end of loop for 'list'

...

while(removing.empty() == false)
{
    list.erase(removing.takeFirst());
}

So, when removing container contains more than 1 element, app crash occurs (SEGMENTATION FAULT) when attempting to erase second element, whereas first was erased successfully. What is the reason and is there any way to remove elements with iterators?

Upvotes: 1

Views: 2277

Answers (2)

Bill
Bill

Reputation: 11832

If for some reason you would like to remove elements from a container in that way then you could try to use QLinkedList instead of QList because Iterators pointing to an item in a QLinkedList remain valid as long as the item exists, whereas iterators to a QList can become invalid after any insertion or removal. I copied this quotation from Qt's documentation: Container Classes.

Upvotes: 4

Dave Mateer
Dave Mateer

Reputation: 17946

No, the iterators will not be valid. If you just want to remove all the elements, use QList::clear(). You can call qDeleteAll() on the QList first if you need to delete the items.

If you want to selectively remove elements using iterators, you can do something like the following. You may need to modify it for memory management.

#include <QtCore>
#include <QtDebug>

int main(int argc, char **argv) {
  QCoreApplication app(argc, argv);

  QList<int> items;
  items << 0 << 1 << 1 << 2 << 3 << 5 << 8 << 13 << 21 << 34 << 55 << 89 << 144;

  QList<int>::iterator i = items.begin();
  while (i != items.end()) {
    if ((*i) % 2 == 0) {
      //  i->DoSomething();  // Not with ints, obviously, but in general.
      i = items.erase(i);  // i points to the next item.
    } else {
      ++i;
    }
  }

  qDebug() << items;

  return app.exec();
}

Upvotes: 1

Related Questions