C++下的内存管理

news2025/1/18 9:40:14

文章目录

  • 内存分布
  • C语言中动态内存管理方法
  • C++内存管理
    • new/delete操作内置类型
    • new和delete操作自定义类型
    • operator new 和 operator delete
    • new和delete的实现原理
    • 定位new表达式
  • malloc/free和new/delete的区别
  • 内存泄漏

内存分布

  • :又叫做堆栈–非静态局部变量/函数参数/返回值等,栈是向下增长的
  • 内存映射段:是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可以使用系统接口创建共享内存,做进程间通信。
  • :用于程序运行时内存分配,堆是可以向上增长的。
  • 数据段:存储全局数据和静态数据
  • 代码段:可执行的代码/只读常量

C语言中动态内存管理方法

  • malloc
  • calloc
  • realloc
  • free

C++内存管理

C++除了继承了C语言的动态内存管理方式,还提出了自己的内存管理方式:new和delete。

new/delete操作内置类型


申请和释放单个元素空间

//申请一个int类型的空间,空间大小为4
int* t1 = new int;

//申请一个int类型的空间,空间大小为4,初始化为10
int* t2 = new int(10);

//销毁一个int类型的单个元素的空间
delete t1;
delete t2;

申请和释放连续元素空间

//申请一个int类型的空间,空间大小为4*10
int* t3 = new int[10];

//申请一个int类型的空间,空间大小为4*10,并且进行初始化
//前三个元素空间初始化为1,2,3,后面的全面初始化为0
int* t4 = new int[10]{1,2,3};

//销毁连续元素空间
delete t3[];
delete t4[];
  • 申请和释放单个元素的空间,使用new和delete操作符
  • 申请和释放连续的空间,使用new[]和delete[]

new和delete操作自定义类型

  • malloc不方便解决动态申请的自定义类型对象的初始化问题。
calss A
{
public:
	A(int a = 0)
	: _a(a);
	{}

	~A()
	{}

private:
	int _a;
}

单个空间开辟

int main()
{
	//创建一个A类型的对象,为这个对象开辟一块空间
	
	//malloc 只是开辟了空间
	A* p1 = (A*)malloc(sizeof(A));
	//new 在开辟空间的同时进行了调用构造函数,进行了初始化
	A* p2 = new A(1);

	free(p1);
	delete p2;
	
	return 0;
}

多个

int main()
{
	A aa1(1);
	A aa2(2);
	A aa3(3);
	
	A* p3 = new A[3]{aa1,aa2,aa3};
	A* p4 = new A[3]{A(1),A(2),A(3)};
	A* p5 = new A[3]{1,2,3};

	delete[] p3;
	delete[] p4;
	delete[] p5;

	return 0;
}

总结

  1. new的本质:开空间+调用构造函数初始化

    • 开空间
    • 调用构造函数
      • 存在默认构造调用默认构造,没有默认构造报错,可以显式的调用构造。
  2. delete的本质:调用析构函数+释放空间

    new失败的时候会抛出异常

    内置类型的空间申请和释放,new和malloc除了用法上没有区别,只有在自定义类型上有区别。

异常捕获

try
{

}
catch
{

}

operator new 和 operator delete

new和delete是用户进行动态内存申请和释放的操作符,operator new和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

  • operator new:该函数的底层实际上是通过malloc来申请空间,当malloc申请空间成功的时候直接返回,申请空间失败的时候,尝试执行空间不足应对措施,如果该应对措施用户设置了,则继续申请,否则抛出异常。

  • operator delete:该函数是通过free来释放空间的。

  • c语言单纯的malloc和free对异常的处理不符合实际的需求,所以对c语言进行了封装,产生了operator new和operator delete函数。

new和delete的实现原理

内置类型
如果申请的是内置类型的空间,new和malloc、delete和free基本上相似,不同的地方是:new/delete申请和释放的是单个元素的空间,new[]delete[]申请的是连续空间,而且new在申请空间时会抛出异常,malloc会返回null。

自定义类型

  • new的原理

    • 调用operator new函数申请空间
    • 在申请的空间上执行构造函数,完成对象的构造
  • delete的原理

    • 在空间上执行析构函数,完成对象中资源的清理工作
    • 调用operator delete函数释放对象的孔吉纳
  • new[N]的原理

    • 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
    • 在申请的空间上执行N次构造函数
  • delete[]的原理

    • 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
    • 调用·operator delete[]释放空间,实际在·operator delete[]中调用operator delete来释放空间

    melloc/freenew/deletenew[]/delete[]一定要配对使用。

  • 构造函数不可以直接显式调用,但是可以通过定位new显式调用

  • 析构函数可以显式调用

定位new表达式

定位new表达式是在已经分配的原始内存空间中调用构造函数初始化一个对象。

格式

n(place_address)type或者new(place_address)type(initializer-list)

new(p1)A(10);
place_address必须是一个指针,initalizer-list是类型的初始化列表。

使用场景
定位new表达式在实际中一般是配合内存池使用,因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显式调构造函数进行初始化。

malloc/free和new/delete的区别

malloc/free和new/delete的共同点:都是堆上申请空间,并且需要用户手动释放。不同的地方是:

  • malloc和free是函数,new和delete是操作符。
  • malloc申请的空间不会初始化,new可以初始化。
  • malloc申请空间时,需要手动计算空间大小并且进行传递,new只需要在其后面跟上空间的类型即可。如果存在多个对象,[]中指定对象个数即可。
  • malloc的返回值为void*,在使用时必须强转,new不需要,因为new后跟的是空间的类型。
  • malloc申请空间失败的时候,返程的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常
  • 申请自定义类型对象的时候,malloc/free之后开辟空间,不会调用构造函数和析构函数。而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理。

内存泄漏

概念

  • 内存泄漏:
    内存泄漏是指因为疏忽或者错误做成程序未能释放已经不再使用的内存的清空,内存泄漏并不是指内存在物理上的小时,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
  • 内存泄漏的危害
    长期运行的程序出现内存泄露,影响很大,如操作系统、后台服务等,出现内存泄漏会导致响应越来越慢,最终卡死。

分类
C/C++程序中一般关心两种内存泄漏:

  • 堆内存泄漏(Heap leak)
    堆内存指的是程序执行中一句需要分配通过malloc/calloc/realloc/new等从堆中分配的一块内存,用完后必须通过调用相应的free或者delete删掉,假设程序的设计错误导致这部分内存没有被释放,那么以后这部分空间的内存将无法再被使用,就会产生Heap Leak。
  • 系统资源泄漏
    指程序使用系统分配的资源,比如文件描述符、管道等没有使用对应的函数释放掉,导致系统资源的浪费,严重可能导致系统效能减少,系统执行不稳定。

避免内存泄漏

  • 工程前期良好的设计规范、养成良好的编码规范,申请的内存空间记着匹配二点去释放。
  • 使用RAII思想或者智能指针来管理资源。
  • 使用内部实现的私有内存管理库。
  • 使用内存泄漏管理工具检测。

解决方案

  • 事前预防型,如智能指针
  • 事后查错型,泄漏检测工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1682503.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Sketch v100 for Mac 安装教程【支持M芯片】

Sketch v100 for Mac 安装教程【支持M芯片】 原文地址:https://blog.csdn.net/weixin_48311847/article/details/139104315

秀某动预约抢票脚本

秀某动预约抢票脚本 小白操作-仅供学习参考 主要流程和功能 初始化和配置变量: confirm_url 和 login_url: 分别存储登录和确认订单的URL。 wait_time: 用户输入的提前多少秒开始执行。 start_time: 开售时间。 DEBUG: 调试标志,用于控制脚本的行为。 浏览…

4. C++入门:内联函数、auto关键字、范围for及nullptr

内联函数 概念 以inline修饰的函数叫做内联函数,编译时C编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率 对比C的宏 C语言不足:宏 #define ADD(x, y) ((x)(y))int main() {int ret…

Spring框架中获取方法参数名称:DefaultParameterNameDiscoverer

DefaultParameterNameDiscoverer 是Spring框架中用于获取方法参数名称的一个类。在Java中,方法的参数名称通常在编译时会丢失,因为Java字节码并不强制要求保留这些信息。Spring提供了一种机制来恢复这些参数名称,这就是通过DefaultParameterN…

工厂模式(简单工厂模式+工厂模式)

工厂模式的目的就是将对象的创建过程隐藏起来,从而达到很高的灵活性,工厂模式分为三类: 简单工厂模式工厂方法模式抽象工厂模式 在没有工厂模式的时候就是,客户需要一辆马车,需要客户亲自去创建一辆马车,…

javaSwing仓库商品管理系统(文档+视频+源码)

摘要 Java swing实现的一款简单的仓库商品管理系统,数据库采用的是mysql,本系统实现了两个角色层面的功能,管理员可以管理用户、仓库、商品信息等。普通用户登录后可以查看商品、仓库信息及个人信息。 系统实现 登录界面: 我们…

MySQL中锁的几种类型

MySQL根据加锁的范围,可以分为全局锁、表级锁、行级锁三类。 2.5.1. 锁定读 2.5.1.1. 共享锁和独占锁 事务的 读-读 情况并不会引起什么问题,对于 写-写、读-写 或 写-读 这些情况可能会引起一些问题,需要使用MVCC或者加锁的方式来解决。在…

ubuntu server 22.04 使用docker安装 onlyoffice 8.0同时添加中文字体、字号

本文主要介绍在ubuntu server 22.04 系统上使用docker安装onlyoffice 8.0同时添加中文字体、字号方法。 1、硬件要求 CPU:双核2 GHz或更高 内存:最少4GB 硬盘:至少40 GB可用空间 Swap file:至少4 GB,但取决于主机操作…

vmware 17pro17.5 bug 严重,建议升级17.52

近日vmware发布17.52 更新,修复了一个重大BUG. 也就是莫名其妙的CPU跟GPU占用问题。 我的系统是WIN11 跟VMWARE17.5..近日莫名其妙的发现即使什么都没运行,GPU占用也高达20%。开始以为中毒了被拿去挖矿了,后面看到VMWARE的这个更新&#xf…

最大连续1的个数(滑动窗口)

算法原理: 这道题大眼一看是关于翻转多少个0的问题,但是,如果你按照这种思维去做题,肯定不容易。所以我们要换一种思维去做,这种思维不是一下就能想到的,所以想不到也情有可原。 题目是:给定一…

中间件是什么?信创中间件有哪些牌子?哪家好用?

当今社会,中间件的重要性日益凸显,尤其是在信创背景下,选择适合的中间件产品对于推动企业数字化转型和升级具有重要意义。今天我们就来聊聊中间件是什么?信创中间件有哪些牌子?哪家好用?仅供参考哈&#xf…

15:00面试,15:08出来,面试问的有点变态。。。。

🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天…

Java开发工具类(JDK、Hutool、Guava)

目录 Java开发常用的工具类1、JDK自带程序读取控制台输入内容(调试程序或者学习的时候比较有用)Arrays工具类 数组转集合Collections 集合工具类 排序Collections 集合工具类 查找Lambda表达式 操作集合 收集、转map、分组 2、Apache 的 commons-lang3 和…

面试框架【面试准备】

前言 2023-9-12 12:12:04 2023-09-14 16:13:04 公开发布于 2024-5-22 00:16:21 以下内容源自《【面试准备】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是https://blog.csdn.net/qq_51625007 禁止其他平…

本地部署Terraria泰拉瑞亚私服并通过内网穿透生成公网地址远程联机

文章目录 前言1. 下载Terraria私服2. 本地运行Terraria 私服3. 本地Terraria私服连接4. Windwos安装Cpolar 工具5. 配置Terraria远程联机地址6. Terraria私服远程联机7. 固定远程联机地址8. 固定的联机地址测试 前言 本文将为你详细介绍在本地如何运行泰拉瑞亚本地私服和结合C…

Nacos 进阶篇---Nacos服务端怎么维护不健康的微服务实例 ?(七)

一、引言 在 Nacos 后台管理服务列表中,我们可以看到微服务列表,其中有一栏叫“健康实例数” (如下图),表示对应的客户端实例信息是否可用状态。 那Nacos服务端是怎么感知客户端的状态是否可用呢 ? 本章…

DataBinding viewBinding(视图绑定与数据双向绑定)简单案例 (kotlin)

先上效果: 4个view的文字都是通过DataBinding填充的。交互事件:点击图片,切换图片 创建项目(android Studio 2023.3.1) Build.gradle(:app) 引入依赖库(完整源码) buildFeatures { vie…

常见算法(1)

1.基本查找/顺序查找 核心:从0索引之后挨个查找 实现代码: public class test {public static void main(String [] arg) throws ParseException {int[] arr {121,85,46,15,55,77,63,49};int number55;System.out.println(bashi(arr,number));}publi…

el-upload上传图片,视频可获取视频时长。

对element-ui组件的upload组件再一次封装&#xff0c;简单记录。下面是效果图。 注意点&#xff1a;该组件现在仅支持单图和单个视频上传。 <template><div :style"myStyle"><divclass"uploads":style"{width: upWith px,height: up…

多商户消费券系统源码(ThinkPHP+FastAdmin+微信公众号)

打造智能促销新体验 一、引言&#xff1a;消费券系统的时代意义 在当今这个数字化高速发展的时代&#xff0c;电子商务和移动支付已经成为人们日常生活的重要组成部分。随着市场竞争的加剧&#xff0c;多商户消费券系统作为一种创新的促销手段&#xff0c;正逐渐受到商家和消…