当前位置: 首页 > ops >正文

QMap清空手动分配的内存

目的

一般用QMap时,直接clear就可以了。
但自己分配内存那种是不能这样操作的,自己分配的内存,还得自己释放,这一个不能忘记,堆内存是需要自己管理的。
堆内存和栈内存的区别:
‌栈内存(Stack Memory)‌:用于存储局部变量和函数调用的上下文信息。它的特点是访问速度快,但容量有限,通常用于存储函数内部的临时变量和返回值。当函数调用结束时,栈内存会自动释放。
‌堆内存(Heap Memory)‌:用于存储动态分配的对象和大型数据结构。它的容量较大,但访问速度较慢,需要程序员手动管理其生命周期,包括分配和释放内存。堆内存适合存储生命周期较长的对象或大量数据。
在C++中,QMap等容器通常使用堆内存来存储数据。这是因为堆内存允许程序在运行时动态地分配和释放内存,而栈内存则由于是自动管理的,不适合存储大量或动态变化的数据。QMap等容器需要存储大量的键值对,并且这些数据的大小和数量在运行时是未知的,因此使用堆内存是更合适的选择。
下面就举例说明,怎么删除比较合适

情况分析

手动申请内存

面临的情况:

#pragma execution_character_set("utf-8")
#include <iostream>
#include <QtCore/QCoreApplication>
#include <QString>
#include <QMap>
#include <QDebug>
using namespace std;
class Student
{
public:Student(int id, const char name[100], float score){qDebug("Student");this->m_id = id;strcpy(this->m_name, name);this->m_score = score;}~Student(){qDebug("~Student");}QString getName(){return QString(this->m_name);}
private:int m_id;char m_name[100];float m_score;
};
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);QMap<int, Student*> stuMaps;Student* stu1 = new Student(1, "小明", 70);Student* stu2 = new Student(2, "小李", 80);Student* stu3 = new Student(3, "小刚", 90);stuMaps.insert(1, stu1);stuMaps.insert(2, stu2);stuMaps.insert(3, stu3);QMap<int, Student*>::iterator iter;for (iter = stuMaps.begin(); iter != stuMaps.end(); iter++){qDebug() << "key=" <<iter.key() << ", value=" << iter.value()->getName();}return a.exec();
}

代码运行情况:
在这里插入图片描述

手动释放内存

如何删除stuMaps呢?直接clear()的话,肯定不行,那样会导致内存泄露,QMap只负责键和值,之外的东西,它就不管了。
一种思路是先删除内存,再清理,这样分两步走,处理的比较好,如下所示:

int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);QMap<int, Student*> stuMaps;Student* stu1 = new Student(1, "小明", 70);Student* stu2 = new Student(2, "小李", 80);Student* stu3 = new Student(3, "小刚", 90);stuMaps.insert(1, stu1);stuMaps.insert(2, stu2);stuMaps.insert(3, stu3);QMap<int, Student*>::iterator iter;for (iter = stuMaps.begin(); iter != stuMaps.end(); iter++){qDebug() << "key=" <<iter.key() << ", value=" << iter.value()->getName();}for (auto it = stuMaps.begin(); it != stuMaps.end(); ++it){delete it.value();it.value() = nullptr;}for (iter = stuMaps.begin(); iter != stuMaps.end(); iter++){qDebug() << "key=" << iter.key() << ", value=" << iter.value();}stuMaps.clear();for (iter = stuMaps.begin(); iter != stuMaps.end(); iter++){qDebug() << "key=" << iter.key() << ", value=" << iter.value()->getName();}return a.exec();
}

运行情况如下:
在这里插入图片描述
从运行情况可知,在执行delete 时申请的student对象得到了释放,达到了目的。

推荐智能指针分配与释放内存

代码更改如下:

#pragma execution_character_set("utf-8")
#include <iostream>
#include <QtCore/QCoreApplication>
#include <QString>
#include <QMap>
#include <QDebug>
#include <Memory>
using namespace std;
class Student
{
public:Student(int id, const char name[100], float score){qDebug("Student");this->m_id = id;strcpy(this->m_name, name);this->m_score = score;}~Student(){qDebug("~Student");}QString getName(){return QString(this->m_name);}
private:int m_id;char m_name[100];float m_score;
};
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);//QMap<int, Student*> stuMaps;{QMap<int, shared_ptr<Student>> stuMaps;//Student* stu1 = new Student(1, "小明", 70);shared_ptr<Student> stu1 = make_shared<Student>(1, "小明", 70);//Student* stu2 = new Student(2, "小李", 80);shared_ptr<Student> stu2 = make_shared<Student>(2, "小李", 80);//Student* stu3 = new Student(3, "小刚", 90);shared_ptr<Student> stu3 = make_shared<Student>(3, "小刚", 90);stuMaps.insert(1, stu1);stuMaps.insert(2, stu2);stuMaps.insert(3, stu3);QMap<int, shared_ptr<Student>>::iterator iter;for (iter = stuMaps.begin(); iter != stuMaps.end(); iter++){qDebug() << "key=" << iter.key() << ", value=" << iter.value()->getName();}stuMaps.clear();for (iter = stuMaps.begin(); iter != stuMaps.end(); iter++){qDebug() << "key=" << iter.key() << ", value=" << iter.value()->getName();}}return a.exec();
}

运行情况如下:
在这里插入图片描述

从运行情况可以看到,在clear()时并未释放内存,但在退出{}时,智能指针就开始释放了这些申请对象,因为退出{}时,智能指针的生命周期结束了,这就是智能指针的作用,利用生命周期进行管理指针。
‌C++智能指针的主要好处包括以下几个方面‌:
‌1、防止内存泄漏‌:智能指针在其析构函数中自动释放所管理的内存。这意味着,一旦智能指针对象超出了作用域或被删除,它所指向的内存就会自动被释放,从而避免了内存泄漏‌
‌2、防止野指针‌:智能指针能够防止野指针的产生。当一个智能指针被赋予一个新的值或销毁时,它所管理的原始指针会自动变为空指针(在大多数情况下),这减少了由于悬垂指针引起的未定义行为‌
‌3、提升异常安全性‌:在异常处理过程中,如果函数提前返回或抛出异常,可能导致分配的内存未能被释放。智能指针能够确保即使在异常发生时,其所管理的内存也能被正确释放,提高了代码的异常安全性‌
‌4、简化资源管理‌:智能指针通过封装原生指针,并利用RAII(资源获取即初始化)技术,确保内存的自动释放,从而避免了手动管理动态分配内存时的复杂性和出错率‌
‌5、多线程安全‌:在多线程环境下,智能指针可以减少因多线程操作共享资源而导致的竞态条件和死锁问题,提高程序的稳定性和可靠性‌

总结

通过上面可知:
在这里插入图片描述

推荐的方式当前是智能指针了,智能指针基本介绍如下:
智能指针是C++11标准引入的一种管理动态内存的工具,用于自动管理动态分配的内存,
避免内存泄漏和悬空指针问题。C++11标准提供了三种智能指针:
unique_ptr、shared_ptr和weak_ptr。
shared_ptr允许多个指针指向同一个对象。
unique_ptr独占所指向的对象,尽量使用unique_ptr,资源占用少,效率更高。
weak_ptr是一种弱引用,指向shared_ptr所管理的对象,但不增加引用计数。

http://www.xdnf.cn/news/11986.html

相关文章:

  • 在WordPress上添加隐私政策页面
  • 深入解析 C++ 多态:从原理到实战
  • 一键试衣,6G显存可跑
  • 6.promise在哪个线程执行?(2)
  • Three.js进阶之音频处理与展示
  • C++.vector 容器(1.5w字)
  • 虚幻网络执行宏-核心作用是根据网络环境中的不同执行环境
  • 抗辐射·耐温差·抑振动:解析猎板PCB真空塞孔在航天电子中的核心价值​
  • 图像局部精度超限情况
  • GDB的调试
  • HTB 靶机 SolarLab Write-up(Medium)
  • Nginx 安全设置问题
  • 计算机I/O系统:数据交互的核心桥梁
  • 论文导读 | 子图匹配最新进展
  • Office安装
  • C#编程过程中变量用中文有啥影响?
  • 【Python零基础入门系列】第7篇:Python中的错误与异常处理
  • 每日八股文6.4
  • C++ 变量二
  • geoai库的训练数据查看与处理
  • 核心机制:拥塞控制
  • 使用pgAdmin导入sql文件
  • 《波段操盘实战技法》速读笔记
  • 数据库-数据查询-in和Not in
  • Linux容器篇、第一章_01Linux系统下 Docker 安装与镜像部署全攻略
  • StringRedisTemplete使用
  • 智能合约安全漏洞解析:从 Reentrancy 到 Integer Overflow
  • 算法训练第八天
  • 电气架构/域控制器/中央计算平台技术论坛
  • 考研系列—操作系统:冲刺笔记(4-5章)