Lesson 03 C/C++内存管理

C++:渴望力量吗,少年?

文章目录

  • 一、C++内存管理方式
    • 1. new/delete操作内置类型
    • 2. new和delete操作自定义类型
  • 二、operator new与operator delete函数
  • 三、new和delete的实现原理
    • 1. 内置类型
    • 2. 自定义类型
  • 四、内存泄漏
    • 1. 什么是内存泄漏
    • 2. 内存泄漏的危害
    • 3. 堆内存泄漏(Heap leak)
    • 4. 解决方案


一、C++内存管理方式

  C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

1. new/delete操作内置类型

int main()
{// 动态申请一个int类型的空间int* ptr4 = new int;// 动态申请一个int类型的空间并初始化为10 int* ptr5 = new int(10);// 动态申请10个int类型的空间int* ptr6 = new int[3];delete ptr4;delete ptr5; delete[] ptr6;// 额外支持开空间+初始化int* p6 = new int(10);//注意这里是赋值为10int* p7 = new int[10]{1,2,3};//和C语言一样,这种情况下没有初始化到的部分默认为0int* p8 = new int[10]{};return 0;
}

在这里插入图片描述

2. new和delete操作自定义类型

  在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。而他们对内置类型是几乎是一样的。

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}private:int _a;
};
int main()
{// malloc没有办法很好支持动态申请的自定义对象初始化A* p1 = (A*)malloc(sizeof(A));//p1->_a = 0;//p1->A(1);// 自定义类型,开空间的同时调用构造函数初始化A* p2 = new A;A* p3 = new A(3);// 自定义类型,调用析构函数+释放空间delete p2;delete p3;A* p4 = new A[10];delete[] p4;/*下面三种写法都是一样的A aa1(1);A aa2(2);A* p5 = new A[10]{ aa1, aa2 };delete[] p5;A* p6 = new A[10]{ A(1), A(2) };delete[] p6;A* p7 = new A[10]{ 1, 2 };delete[] p7;
*/return 0;
}

二、operator new与operator delete函数

  new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
  operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,尝试执行空间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常

typedef char DataType;
class Stack
{
public:Stack(size_t capacity = 4){cout << "Stack()" << endl;_array = new DataType[capacity];//析构函数对应也得用delete释放空间//_array = new char[0x7ffffffffff];//如果取消注释,那么对应的第二段代码会抛出异常_capacity = capacity;_size = 0;}void Push(DataType data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){cout << "~Stack()" << endl;delete[] _array;_array = nullptr;_size = _capacity = 0;}
private:// 内置类型DataType* _array;int _capacity;int _size;
};
class A
{
public:A(int a = 0):_a1(a){}~A(){cout << "~A()" << endl;}private:int _a1;
};
int main()
{Stack* pst1 = (Stack*)operator new(sizeof(Stack));//相当于malloc,创造它是为了符合抛出异常的方式operator delete(pst1);//相当于free//其实上面两个函数主要都不是让我们直接使用,而是分别封装在new和delete中,new就相当于operator new和调用构造函数Stack* pst2 = new Stack;delete pst2;//free(pst2);A* p2 = new A[10];delete[] p2;return 0;
}

  new和delete一定要匹配使用,否则后果可能是未定义的!!!

三、new和delete的实现原理

1. 内置类型

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

2. 自定义类型

(1)new的原理
    a.调用operator new函数申请空间
    b.在申请的空间上执行构造函数,完成对象的构造
(2)delete的原理
    a.在空间上执行析构函数,完成对象中资源的清理工作
    b.调用operator delete函数释放对象的空间
(3)new T[N]的原理
    a.调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
    b.在申请的空间上执行N次构造函数
(4)delete[]的原理
    a.在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
    b.调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间

四、内存泄漏

1. 什么是内存泄漏

  内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

2. 内存泄漏的危害

  长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。

void MemoryLeaks()
{// 1.内存申请了忘记释放int* p1 = (int*)malloc(sizeof(int)); int* p2 = new int;// 2.异常安全问题int* p3 = new int[10];Func(); // 这里Func函数抛异常导致 delete[] p3未执行,p3没被释放. delete[] p3;
}

3. 堆内存泄漏(Heap leak)

  作为初学者,我们更加关注的是这方面的泄露。堆内存指的是程序执行中依据须要分配通过malloc / calloc / realloc / new等从堆中分配的一块内存,用完后必须通过调用相应的 free或者delete 删掉。假设程序的设计错误导致这部分内存没有被释放,那么以后这部分空间将无法再被使用,就会产生Heap Leak。

4. 解决方案

内存泄漏非常常见,一般解决方案分为两种:
(1)事前预防型。如智能指针等;
(2)事后查错型。如泄漏检测工具。


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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python的数据分析包Pandas?示例文章完成版来啦~

文章目录 前言一、Pandas简介二、Python Pandas的使用 总结 前言 pandas 是基于NumPy 的一种工具&#xff0c;该工具是为了解决数据分析任务而创建的。 Pandas 是python的一个数据分析包&#xff0c;最初由AQR Capital Management于2008年4月开发&#xff0c;并于2009年底开源…

设计模式-行为型模式-责任链模式

一、什么是责任链模式 责任链模式是一种设计模式。在责任链模式里&#xff0c;很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递&#xff0c;直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求&…

Vue 路由缓存 防止路由切换数据丢失 路由的生命周期

在切换路由的时候&#xff0c;如果写好了一丢数据在去切换路由在回到写好的数据的路由去将会丢失&#xff0c;这时可以使用路由缓存技术进行保存&#xff0c;这样两个界面来回换数据也不会丢失 在 < router-view >展示的内容都不会被销毁&#xff0c;路由来回切换数据也…

wpf devexpress Property Grid创建属性定义

WPF Property Grid控件使用属性定义定义如何做和显示 本教程示范如何绑定WP Property Grid控件到数据和创建属性定义。 执行如下步骤 第一步-创建属性定义 添加PropertyGridControl组件到项目。 打开工具箱在vs&#xff0c;定位到DX.23.1: Data 面板&#xff0c;选择Prope…

sqli-labs关卡18(基于http头部报错盲注)通关思路

文章目录 前言一、靶场通关需要了解的知识点1、什么是http请求头2、为什么http头部可以进行注入 二、靶场第十八关通关思路1、判断注入点2、爆数据库名3、爆数据库表4、爆数据库列5、爆数据库关键信息 总结 前言 此文章只用于学习和反思巩固sql注入知识&#xff0c;禁止用于做…

在做题中学习(30):字符串相加

思路&#xff1a; 相加时要转换成对应的数字&#xff0c;所以让字符数字-0 如‘9’-‘0’&#xff08;ASCII&#xff09;57-489 9110&#xff0c;会进1&#xff0c;把进位保存起来&#xff0c;只取0头插到新串里。 头插时要转换对应字符数字&#xff0c;所以让对应的数字‘…

freetype将字符串制作成位图并显示过程详解

在流媒体项目中字幕显示是不可或缺的一环&#xff0c;一般会有字幕流在视频播放过程中进行显示&#xff1b;不过还有很多情况是从头到尾只在视频的某个区域显示某些文字&#xff0c;例如某个电视台的log&#xff1b;这种也称为字幕&#xff0c;如果想要将这些字符串显示到视频&…

谈谈如何写作(二)

序言 没有什么比一套好理论更有用了。——库尔特勒温 谈谈如何写作系列今天进入第二篇&#xff0c;第一篇请速戳&#xff1a;谈谈如何写作&#xff08;一&#xff09; 今天&#xff0c;博主从如何写报告讲起。 Q&#xff1a;如何写报告 如何写报告呢&#xff1f; 当每位盆友接到…

linux进程间通信之信号

摘要 本文旨在研究Linux进程间通信的机制之一&#xff1a;信号。信号是由操作系统来处理的&#xff0c;说明信号的处理在内核态。信号不一定会立即被处理&#xff0c;此时会储存在信 号的信号表中。最后&#xff0c;我们会对这种通信方式的优缺点进行全面的分析&#xff0c;并给…

Arduino驱动LM35线性温度传感器(温湿度传感器)

目录 1、传感器特性 2、控制器和传感器连线图 3、驱动程序 LM35半导体的温度传感器,可以用来对环境温度进行定性的检测。LM35半导体温度传感器是美国国家半导体公司生产的线性温度传感器。其测温范围是-40℃到150℃,灵敏度为10mV/℃,输出电压与温度成正比。

Linux命令之查看文件和权限修改操作

目录 查看文件 1. cat --- 将文件中的内容打印在输出设备 2. more --- 分页显示文件内容 3.less ---查看文件内容 4. head -- 查看文件前n行内容 5.tail -- 查看指定文件的后n行内容或实时监测文件 6. wc -- 可计算文件的字节数、字数和列数 文件搜索 1.which --- 获取…

柯桥会计培训|中级会计职称,考过中级,可以从事哪些工作?

拿下中级会计证书后&#xff0c;可以从事哪些工作呢&#xff1f;一起来看看吧~ 财务经理 财务经理可以说是会计人梦寐以求的岗位&#xff0c;上可以和老板畅聊公司财务情况&#xff0c;下可以管理整个财务部。但是在财务管理水平日益成为企业核心竞争力的今天&#xff0c;企业…