1

I have QVector<QSharedPointer<SomeData> > DataVec as a field of one class in a big objected-oriented project. Program gets memory overflow during cycled execution of code part, where large memory is allocated, controlled by QSharedPointers.

During program run cycle, DataVec is filled with

DataVec.push_back(QSharedPointer<SomeData>(new SomeData()));

Will QSharedPointer be deleted (released) after calling DataVec.pop.back() or DataVec.clear()?

I think: no. We must call explicitly destructor for QSharedPointer (I cannot see also the method like boost::shared_ptr::reset() in Qt). Than, SomeData default destructor (SomeData have only standard Qt containers as fields) will be called if we have no more QSharedPointers that point to SomeData instance concerned, and the memory will be released. Now, I only do pop_back(): it seems, I just loose pointers to unreleased data (after execution, valgrind indicates I have definitely lost blocks, and I suppose they originate from here).

So, finally, am I right? And how can I delete QSharedPointer from container the right way?

EDIT 1: The method like boost::shared_ptr::reset() in Qt is QSharedPointer::clear().

demonplus
  • 5,613
  • 12
  • 49
  • 68
John_West
  • 2,239
  • 4
  • 24
  • 44

1 Answers1

5

QVector will call the destructor of its item when the item is removed from it using pop_back, clear or any other way.

If there is a shared pointer to an object in the vector and there is no more shared pointers to this object anywhere in the program, removing a shared pointer from the vector will definitely cause object deleting.

If there are shared pointers to this object somewhere else, the object will not be deleted until all references are removed.

Pavel Strakhov
  • 39,123
  • 5
  • 88
  • 127
  • And if we have QSharedPointers as fields in our object and their ref.counts are >0 (they were got from other place, where these "other" data are still needed)? QSharedPointer will wait for these, and it can cause memory consumption (even there is no memory leak and deadlock, because after cycle this field can be removed). I should use QWeakPointer as field, shouldn't I? – John_West Aug 02 '13 at 21:03
  • Consider manual deleting or clearing the object containing the pointers when you need to delete the object, e.g. `data_vec.pop_back(); our_object.clear_fields();`. `QWeakPointer` also can be used in this case. It's hard to tell what would be simplier without whole picture. – Pavel Strakhov Aug 02 '13 at 21:10
  • Did you mean `data_vec[data_vec.size()-1]->clear_fields(); data_vec.pop_back()`? Does `.clear_fields()` contain `QSharedPointer::clear()` for these fields? – John_West Aug 02 '13 at 21:18
  • No, I talk about shared pointers to the object that is being destroying. Pointers to other data doesn't affect destroying the object. – Pavel Strakhov Aug 02 '13 at 21:28
  • So, if I have QSharedPointer and OneData contains QSharedPointer as a field, and OtherData shouldn't be deleted, I simply could free QSharedPointer (calling data_vec.pop_back())? – John_West Aug 02 '13 at 22:00
  • Yes, assuming that there are other pointers to OtherData (otherwise it will be deleted when no pointers left). – Pavel Strakhov Aug 02 '13 at 22:09
  • 1
    If the other data shouldn't be deleted, you probably have QSharedPointer instances pointing to it somewhere else? Then it's not a problem. – Frank Osterfeld Aug 03 '13 at 07:46