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

[C++] 动态内存与智能指针

众所周知,C++五大内存区:全局数据区(静态区)、代码区、栈区、堆区、常量区。
全局数据区(静态区):存放全局变量,静态数据和常量;
代码区:存放所有类成员函数和非成员函数代码,函数体的二进制代码。
栈区:存放为运行函数而分配的局部变量、函数参数、返回数据、返回地址等。
堆区:new、malloc、realloc分配的内存块,一般编译器不会释放内存,需要用程序释放,内存泄露通常说的就是堆区。
常量区:存放常量的,不允许修改。

其中,堆区就是动态内存的区域,就是程序员自己分配和释放内存的区域。

1.智能指针

1.1 介绍

头文件:#include<memory>

智能指针是模板。

shared_ptr:共享指针,允许多个指针指向同一个对象

unique_ptr:独占指针,只允许一个指针指向一个对象

weak_ptr:弱引用,指向shared_ptr所管理的对象。

特点:智能指针可以自动释放所指向的对象的内存。

1.2 shared_ptr类

形式:shared_ptr<T> ptrname;

特点:每个shared_ptr都有一个关联的计数器,来记录有多少个智能指针指向这个对象,

我们拷贝一个shared_ptr,计数器会递增,如:

        1.当用一个shared_ptr初始化另一个shared_ptr

        2.当把一个shared_ptr作为参数传递给一个函数

        3.当把一个shared_ptr作为一个函数返回值时  

我们销毁一个shared_ptr,或给一个shared_ptr赋值时,计数器会递减,如:

        1.局部shared_ptr离开一个作用域,会被销毁,则指向这个对象的其它shared_ptr指针的计数器会递减

当计数器为0时(即没有智能指针指向这个对象了),将会调用这个对象的析构函数销毁它,并释放内存。

T:是一个类型,可以是内置类型、容器等等。

操作含义
shared_ptr<T> sp空智能指针,指向类型为T的对象
sp将sp作为条件判断,如果sp指向一个对象,则为true,否则为false
*sp解引用sp,获得它指向的对象
sp->mem等价于(*sp)->mem,调用sp指向对象的成员
sp.get()返回sp中保存的指针。注意:若智能指针释放了其对象,返回的指针所指向的对象也就消失了。

swap(sp1,sp2)

sq.swap(sp2)

交换两个智能指针
make_shared<T> (args)返回一个shared_ptr,指向类型为T的对象。并且使用args对对象进行初始化。这是最安全的分配和使用动态内存的方法
shared_ptr<T> sp (sq)sp是sq的拷贝,此操作会递增sq的计数器。sq中的指针必须能转换为T*
sp=sqsp是sq的拷贝,此操作会递增sq的计数器,递减sp的计数器。
sp.unique()若sp.use_count为1,则为true,否则,则为false
sp.use_count()返回与sp共享对象的智能指针数量。可能会很慢

注意:

        由于在最后一个shared_ptr销毁前,这个对象不会被销毁,所以就需要保证当这个shared_ptr在后面不会再使用的时候就要销毁它。如:一个容器里,存有多个shared_ptr,但是用到后面,我只需要使用其中的一部分shared_ptr,这时候我就要调用容器的erase函数,来将不用的shared_ptr给销毁掉,避免内存浪费。

1.3 unique_ptr类

操作含义
unique_ptr<T> up空智能指针,指向类型为T的对象
up将up作为条件判断,如果sp指向一个对象,则为true,否则为false
*up解引用up,获得它指向的对象
up->mem等价于(*up)->mem,调用up指向对象的成员
up.get()返回up中保存的指针。注意:若智能指针释放了其对象,返回的指针所指向的对象也就消失了。

swap(up1,up2)

up.swap(up2)

交换两个智能指针

2.动态内存

2.1 使用动态内存资源的类

一般在以下情况下,程序要使用动态内存资源:

        1.程序不知道这个类需要分配多少对象。如:容器

        2.程序不知道所需对象的准确类型。

        3.程序需要在多个对象间共享数据。

3.动态内存与智能指针

http://www.lryc.cn/news/66090.html

相关文章:

  • 多态的原理
  • RK3588平台开发系列讲解(内存篇)Linux 伙伴系统数据结构
  • Windows(MFC/C++)上进程间通讯的几种简单又实用的方法
  • 嘉兴桐乡会计考证培训-备考中级职称有必要报班吗?
  • java元注解和自定义注解的区别
  • 技术到底是什么
  • 什么CRM客户管理系统最好?
  • 吴军《计算之魂》读后感
  • CSS进阶
  • 金兰组织 | 2023金兰解决方案集经营管理篇正式发布
  • 【python】pytorch包:深度学习(序章)
  • HTML <acronym> 标签
  • python基本数据类型 - 字典集合
  • python数据类型总结
  • TS内置类型总结
  • Spring Cloud Alibaba: Gateway 网关过滤器 GatewayGatewayFilter factory (记录)
  • Windows Server 2016版本说明
  • 车载红外夜视「升温」
  • ext3 文件系统的特点、优缺点以及使用场景
  • rk3568 修改开机logo
  • golang实现关键路径算法
  • Overcoming catastrophic forgetting in neural networks
  • [Linux] Linux文件系统
  • 有仰拍相机和俯拍相机时,俯拍相机中心和吸嘴中心的标定
  • 【Vue学习笔记5】Vue3中的响应式:ref和reactive、watchEffect和watch
  • 自动化测试工具的基本原理以及应用场景
  • 《Java虚拟机学习》 java代码的运行过程
  • 关于Intel处理器架构中AVX2里Gather特性的说明
  • UNIX常用命令(C站最全,一文通关)
  • Vue监听属性详细讲解