前言
最近在搞qt,捡起了荒废很多年的C++,这让本来底子不好的脑子雪上加霜,如今对比起其他编程语言来讲,C++语法变态的一批。。。
百度了一圈QVector、QList什么的尝试了很多方法都各种报错,后来还是偶然看到一个网友评论说的“反正都是存指针无所谓了”点醒了我。
QVector、QList什么的到底用啥存
这里引用上文的一段话:
如何选择这三个容器中哪一个,应根据你的需要而定,一般应遵循下面的原则:
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