飞道的博客

QT QList C++ 自定义类 数组 存储 Linux

786人阅读  评论(0)

前言

最近在搞qt,捡起了荒废很多年的C++,这让本来底子不好的脑子雪上加霜,如今对比起其他编程语言来讲,C++语法变态的一批。。。

百度了一圈QVector、QList什么的尝试了很多方法都各种报错,后来还是偶然看到一个网友评论说的“反正都是存指针无所谓了”点醒了我。


QVector、QList什么的到底用啥存

参考:QList (链表) & QVector (数组)

这里引用上文的一段话:

如何选择这三个容器中哪一个,应根据你的需要而定,一般应遵循下面的原则:
1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。


这里我用来存储服务器的每个会话线程,会有频繁的断开和连接事件所以使用QList。


实现方法

新建一个类,继承QObject,取名为myclass_win。编译器用的MinGW。

main.cpp

#include <QCoreApplication>
#include<myclass_win.h>
#include<QDebug>
int main(int argc, char *argv[])
{
   
    QCoreApplication a(argc, argv);
    QList<myclass_win*> classarr;

    for(int i=0;i<50000;i++){
   
        myclass_win *c=new myclass_win();
        classarr.append(c);
    }

    qDebug()<<classarr.length();

    //释放内存
    qDeleteAll(classarr);
    classarr.clear();
    qDebug()<<classarr.length();



    return a.exec();
}

正常情况下,这样用就可以了。

然而

如果你是linux系统,这样写会报错,原因是gcc编译器需要我们指定赋值和拷贝函数。

首先我们需要简单的改造一下我们的自定义类,满足QList使用方式的类需要有构造函数赋值函数拷贝函数3个基本函数,qt新建的类中不包含后两个函数,我们需要在头文件中手动补全它。

Linux系统上的代码

Linux使用GCC编译器。
myclass.h

#ifndef MYCLASS_H
#define MYCLASS_H

#include <QObject>

class myclass : public QObject
{
   
    Q_OBJECT
public:
    explicit myclass(int num,QObject *parent = nullptr);// 构造函数
	/*以下是我们手动添加的函数*/
    myclass(const myclass&);//拷贝函数
    myclass& operator=(const myclass&);//赋值函数



    int add(int a,int b);
    int getnum();
    int num;
signals:

};

#endif // MYCLASS_H

myclass.cpp

#include "myclass.h"

// 构造函数
myclass::myclass(int num,QObject *parent) : QObject(parent)
{
   
this->num=num;
}

int myclass::add(int a, int b)
{
   
    return a+b;
}

int myclass::getnum()
{
   
return this->num;
}

main.cpp

#include <QCoreApplication>
#include<qdebug.h>
#include<myclass.h>


int main(int argc, char *argv[])
{
   
    QCoreApplication a(argc, argv);
	//注意这里才是核心所在,一定要指定为<myclass*>,即指针类型。
	//不然当你在调用classarr[i].add()的时候,系统会new一个myclass然后调用调用拷贝函数去赋值。
	//这样的情况导致我们多写了很多代码且很被动,甚至有些变量状态我们无法还原!
    QList<myclass*> classarr;
    for (int i=0;i<20;i++){
   
        myclass *c=new myclass(i+1);
        classarr.append(c);
    }


    for  (int i=0;i<classarr.count();i++){
   
        qDebug()<< classarr[i]->add(0,i)<<classarr[i]->getnum();
    }

    //Qlist内存释放
    //指针的Qlist需要先使用qDeleteAll()方法全部delete一遍。
    qDeleteAll(classarr);
    classarr.clear();
    return a.exec();
}

然而!!!!

上面的代码都不是问题,卡了我两个多小时的问题在于Linux下的垃圾回收。。。

不知道为啥在linux中,qDeleteAll后指针的确被删除了但是内存没有归还给系统,Win10就正常。我遇到了和下面帖子作者一样的问题,貌似我们都是linux环境下出现的问题。

用这哥们的话来讲:

参考:奇怪的 内存 释放问题。delete 之后,内存无法释放
内存并没有泄露,只是没有归还给系统。如果在这段程序 的后面 继续分配内存的话,进程的heap 是不会继续增加的

实际上也如此,在执行完qDeleteAll()以后,再new相同数量的myclass,内存是不会增长的。但也不会被释放。尴尬。。

一些系统在一些情况下对释放的内存可能并不立即被系统收回,而只是进行相应的标记,在程序下一次申请时可直接使用,从而提高效率,但在系统需要内存且内存不足时这部分内存才被系统回收

上面这哥们前半部分可能说的对,但后半部分我试过了,至少在我内存不足时那部分内存是不会被回收的。查阅很多资料无果,这里懂的朋友麻烦评论下,暂时不搞了。感谢。


转载:https://blog.csdn.net/cbaili/article/details/113819352
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场