簡體   English   中英

Qt QList-removeAll釋放內存

[英]Qt QList - removeAll deallocating memory

我有一個像這樣的MyClass指針的QList

QList<MyClass*> myList;

當我調用myList.removeAll(someObjPtr); 它不僅從QList刪除指針,還內部調用了delete。 有沒有辦法解決這個問題,或者有替代的QList方法可以刪除元素而不分配它們?

編輯:removeAll的內部:

template <typename T>
Q_OUTOFLINE_TEMPLATE int QList<T>::removeAll(const T &_t)
{
    int index = indexOf(_t);
    if (index == -1)
        return 0;

    const T t = _t;
    detach();

    Node *i = reinterpret_cast<Node *>(p.at(index));
    Node *e = reinterpret_cast<Node *>(p.end());
    Node *n = i;
    node_destruct(i);
    while (++i != e) {
        if (i->t() == t)
            node_destruct(i);
        else
            *n++ = *i;
    }

    int removedCount = e - n;
    d->end -= removedCount;
    return removedCount;
}

如您所見,它調用node_destruct,它執行以下操作:

template <typename T>
Q_INLINE_TEMPLATE void QList<T>::node_destruct(Node *n)
{
    if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) delete reinterpret_cast<T*>(n->v);
    else if (QTypeInfo<T>::isComplex) reinterpret_cast<T*>(n)->~T();
}

如您所見,有一個刪除被調用。

QList與Qt 3的QPtrList沒有QPtrList

沒有QList方法以特殊方式解釋存儲的指針。 您必須對它進行了錯誤的測試。 例如,以下代碼愉快地泄漏了兩個C實例,並且從不刪除它們。

也許您在考慮QtAlgorithmsqDeleteAll 刪除實例。

請注意, QList的實現可以分配每個項目的內存以在其中存儲您的實例,並在適當時釋放該內存。 QList實現決不會刪除您存儲在列表中的指針: QList解釋存儲的數據的唯一方法是通過其類型,然后才可以確定這些項是否可移動存儲以及它們是否適合void*還是需要單獨分配它們。 實際上, 所有指針類型都存儲在QList ,就像它是QVector ,在開頭和結尾都添加了一些空間,使push_frontpush_back攤銷了O(1)成本。

#include <QtCore>

struct C {
  static int ctr;
  C() { ctr ++; }
  ~C() { ctr --; qDebug() << (void*)this << "C instance destructed"; }
};
int C::ctr;

int main() {
  auto c1 = new C, c2 = new C;
  auto list1 = QList<C*>() << c1 << c2;
  list1.removeAll(c1); // doesn't delete the pointed-to objects
  list1.removeAll(c2);
  Q_ASSERT(list1.isEmpty());
  Q_ASSERT(C::ctr == 2);
  // we'll happily leak both instances above

  auto list2 = QList<C*>() << new C << new C << new C;
  qDeleteAll(list2); // invokes delete on all objects
  Q_ASSERT(C::ctr == 2);
}

node_destruct不會刪除指針QList指向的對象。 如果仔細觀察,它只會刪除大型和靜態類型的n->v QList在內部在堆上分配大型和靜態類型,因此刪除是必需的。

對於指針類型, QTypeInfo<T>專長是:

template <typename T>
class QTypeInfo<T*>
{
public:
    enum {
        isPointer = true,
        isComplex = false,
        isStatic = false,
        isLarge = false,
        isDummy = false
    };
};

如您所見,指針既不大也不靜態,因此不會被刪除

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM