QList指针中的clear后不会自动释放内存,需要之前调用qDeleteAll()

本文详细讲解了QList在Qt中如何进行内存管理,包括非指针类型和指针类型的对象释放方法。对于非指针类型,直接使用clear()即可;而指针类型则需先调用qDeleteAll()再clear()。

QList<T> 的释放分两种情况:

1.T的类型为非指针,这时候直接调用clear()方法就可以释放了,看如下测试代码

#include <QtCore/QCoreApplication>#include <QList>#include <QString>
int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    typedef struct _test    {        int id;        QString name;        QString sex;    }Por_test;    QList<Por_test>  slist;    for (int i=0;i<100000;i++)    {        Por_test s;        s.id = 1;        s.name = QString("hello World!");        s.sex = QString("男");        slist.append(s);    }    slist.clear();    return a.exec();}

将上面代码中的slist.clear(); 注释掉,内存显示为如下(任务管理器里的截图)

111

如不去掉的话,内存显示如下图

22222

2.T的类型为指针的情况,这时候直接调用clear()方法将不能释放,先看代码

#include <QtCore/QCoreApplication>
#include <QList>
#include <QString>
int main(int argc, char *argv[])
{   
    QCoreApplication a(argc, argv);   
     typedef struct _test    
     {        int id;     
        QString name;     
           QString sex;   
            }Por_test;  
    QList<Por_test *>  slist;  
      for (int i=0;i<100000;i++) 
         {      
           Por_test *s = new Por_test();       
            s->id = 1;      
              s->name = QString("hello World!");   
                   s->sex = QString("男?"); 
                          slist.append(s);  
                            }//  
                              qDeleteAll(slist);   
                               slist.clear();    return a.exec();}

上面代码运行后的内存情况如下图

3333

说明当T的类型为指针时,调用clear()方法并不能释放其内存

此时void qDeleteAll ( const Container & c )方法将派上用场了,将上面代码中的注释去掉以后,

再次运行程序,此时的内存情况如下图

4444

通过对比靓图,可以看出,内存已经释放,我们再来看下qt助手中qDeleteAll 方法的说明

void qDeleteAll ( ForwardIterator begin, ForwardIterator end )

Deletes all the items in the range [beginend) using the C++ delete operator. The item type must be a pointer type (for example, QWidget *).

Example:

 QList<Employee *> list; list.append(new Employee("Blackpool", "Stephen")); list.append(new Employee("Twist", "Oliver")); qDeleteAll(list.begin(), list.end()); list.clear();

Notice that qDeleteAll() doesn't remove the items from the container; it merely calls delete on them. In the example above, we call clear() on the container to remove the items.

This function can also be used to delete items stored in associative containers, such as QMap and QHash. Only the objects stored in each container will be deleted by this function; objects used as keys will not be deleted.

See also forward iterators.

void qDeleteAll ( const Container & c )

This is an overloaded member function, provided for convenience.

This is the same as qDeleteAll(c.begin(), c.end()).

 

上面qDeleteAll 方法的说明,已经很清楚了,如果T为指针类型时,释放内存须在clear方法前加上qDeleteAll 方法。

### 清理 QList 内容前的准备工作 当使用 `QList` 的 `clear()` 方法时,它仅会移除列表中的所有元素,但不会自动释放这些元素所占用的内存。因此,在调用 `clear()` 之前,需根据 `QList` 中存储的数据类型进行相应的清理准备。 如果 `QList` 存储的是指针类型(例如 `QList<A*>`),调用 `clear()` 不会释放这些指针所指向的对象的内存[^1]。此时应手动删除每个指针所指向的对象,以避免内存泄漏。例如: ```cpp QList<A*> qlistas; qlistas.append(new A()); qlistas.append(new A()); for (A* item : qlistas) { delete item; } qlistas.clear(); ``` 对于包含指针的 `QList`,可使用 `qDeleteAll()` 函数简化清理过程。该函数会删除列表中所有指针所指向的对象,但不会自动调用 `clear()`,因此仍需手动清空列表: ```cpp QList<Employee*> list; list.append(new Employee("Blackpool", "Stephen")); list.append(new Employee("Twist", "Oliver")); qDeleteAll(list); list.clear(); ``` 如果 `QList` 存储的是非指针类型(例如 `QList<int>` 或 `QList<QString>`),则直接调用 `clear()` 即可释放内存,无需额外操作。例如: ```cpp QList<int> list; list << 1 << 2 << 3; list.clear(); // 直接清空,内存自动释放 ``` 在多线程环境中使用 `QList` 时,应确保在调用 `clear()` 前没有其他线程正在访问或修改列表。可使用 `QMutex` 或 `QMutexLocker` 来保证线程安全: ```cpp QMutex mutex; QList<WidgetInfo> dataList; void addData(const WidgetInfo &info) { QMutexLocker locker(&mutex); dataList.append(info); } void clearData() { QMutexLocker locker(&mutex); dataList.clear(); } ``` 如果 `QList` 中存储的是嵌套结构(例如 `QList<QList<T>>`),则需递归清理每个子列表。例如,若 `T` 是指针类型,应先删除子列表中的所有对象,再清空主列表: ```cpp QList<QList<A*>> nestedList; nestedList.append(QList<A*>() << new A() << new A()); for (QList<A*>& sublist : nestedList) { qDeleteAll(sublist); } nestedList.clear(); ``` 此外,若 `QList` 中的元素与信号和槽机制相关联(例如 `QListWidget::currentItemChanged`),应在调用 `clear()` 前断开相关信号连接,以避免触发无效操作: ```cpp disconnect(listWidget, &QListWidget::currentItemChanged, this, &MyClass::handleItemChange); listWidget->clear(); connect(listWidget, &QListWidget::currentItemChanged, this, &MyClass::handleItemChange); ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值