【从小白到大白05】c和c++内存管理
创始人
2024-03-30 07:14:20
0

c和c++内存管理

image-20221022150510788

文章目录

  • c和c++内存管理
  • c++内存管理方式
      • new/delete操作内置类型
        • new申请动态空间
        • delete释放空间
      • new和delete操作自定义类型
      • operator new与operator delete函数
    • new[]和delete[]
    • 定位new(placement-new)
      • 总结以上
    • 内存泄露
        • 以上就是全部内容啦,如果有你对哪点不清晰或者有问题的话,请在评论下留言,我会尽我所能答复哒

c和c++的大致内存分配如图所示:

image-20221015120533944

1.栈又称堆栈—存放非静态局部变量、函数参数、返回值等等,另外栈是向下增长的。

函数调用时创建,函数结束即销毁。(即用即取)

2.内存映射段—高效的I/O映射方式,用于装载一个共享的动态内存库,用户可以使用系统接口

创建共享内存,做到进程中通信。

3.堆—用于程序运行时动态内存分配,另外堆是向上增长的。

4.数据段—用于存储全局数据和静态数据

**5.代码段—可执行代码或只读变量。**然而平时咱们敲的代码(在编译器上)是存在文件里(磁盘)。–这里别搞混啦!

代码在电脑上跑起来时会生成一个.exe文件,运行它时会形成进程,进程会向操作系统申请虚拟进程内存空间。原先在32位操作系统下的32位程序:指针大小为4byte,那么虚拟进程内存空间大约为4G(232byte);而到后来的科技发展到32位操作系统已经满足不了人们的需求,则又有了现在广泛运用的64位操作系统下的64位程序:指针为8byte,那么虚拟进程内存空间大约为232*4G(2^64byte)

【1G=1024MB=1024*1024KB=1024 *1024 *1024byte约等于2^30byte】

第一个空间—(0x00000000)—空指针

c++内存管理方式

new/delete操作内置类型

new申请动态空间

image-20221015141613547

image-20221015141745173

delete释放空间

int main()
{int* ptr1 = new int;//动态申请一块int类型的空间--没有初始化delete ptr1;int* ptr2 = new int(1);//动态申请一块int类型的空间--初始化为1delete ptr2;int* ptr3 = new int[10];//动态深10块int类型空间--没有初始化delete ptr3;int* ptr4 = new int[10]{ 1,2,3,4,5 };动态深10块int类型空间--初始化为1,2,3,4,5其余自动初始化为0delete ptr4;return 0;
}

new和delete操作自定义类型

在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会

image-20221015142716246

注意:new和delete必须要配对出现!

第一种情况:我new了一个自定义类型,然而delete了一组自定义类型—没有报错然而死循环了!

image-20221015143142092

第二种情况:我new了一个自定义类型,然而delete了一组自定义类型,但是我把析构函数屏蔽掉了—没有报错正常运行!

image-20221015143336755

第三种情况:我new了一个自定义类型,然而free了一个自定义类型—没有报错正常运行!

image-20221015143618079

但是你并不知道在不报错的时候会发生什么,比如内存泄露等等

第三种情况:我new了10个对象,然而只delete一个对象—会报错

image-20221015144636118

然而我把析构函数屏蔽掉则不会报错—正常运行!

image-20221015144812029

所以我们在使用new和delete的时候一定要匹配阿!!!

operator new与operator delete函数

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

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

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

如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:

new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。

new[]和delete[]

前提:

new的原理:调用operator new函数申请空间;在申请空间上调用构造函数完成初始化;

delete的原理:在空间上调用析构函数完成对对象资源的清理;调用operator delete函数释放对象的空间

所以同样的也有:

new对象[N]的工作原理:newA [N]调用operator new[]函数,实际上operator new[]函数是调用了operator new函数完成N个对象的空间申请;在申请空间上调用N次构造函数完成N个对象的初始化;

delete[N]的工作原理:调用N次析构函数完成对对象资源的清理;delete[N]函数调用了operator delete[]函数,实际上是operator delete[]函数调用了operator delete函数来对对象释放空间;

image-20221022131825099

这里贴一份代码后续要用到噢~

class A
{
public:A(int a = 0):_a(a){cout << "调用构造-A()" << endl;}~A(){cout << "调用析构函数-~A()" << endl;}
private:int _a;
};int main()
{A* p2 = (A*)malloc(sizeof(A));if (p2 == nullptr){perror("malloc fail");exit(-1);}new (p2)A(1);p2->~A();free(p2);return 0;
}

定位new(placement-new)

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

image-20221022142225073

定位new表达式:new(对象)构造函数(参数:用来初始化,不用初始化可以不写)

比如:new(p2)A(1)

image-20221022133448320

总结以上

mallocfreenewdelete
共同点从堆上申请空间,并且需要手动释放——从堆上申请空间,并且需要手动释放
不同点是函数是函数是操作符是操作符
申请空间时,需要手动计算大小不需要计算大小,new后接类型[个数]——
返回值void*,返回时需要强转——后接类型
申请空间时要判空,申请失败时返回NULL——不需要判空,但失败会抛异常
申请自定义类型时只会申请开辟空间,不会初始化只会释放空间不仅会开辟空间,还会调用对象的构造函数初始化会调用对象的析构函数完成对象资源的清理然后释放空间

内存泄露

内存泄漏指:**因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。**内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。(进程结束前泄露-对某块空间无法使用-比如失去指向这块内存的指针,进程结束后内存还给操作系统)

内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现

内存泄漏会导致响应越来越慢,最终卡死。(不怕突然泄露,就怕不知不觉之间泄露小部分空间,长时间累积导致系统变卡顿-温水煮青蛙)

相当于我们生病,不怕急性病(当前医疗环境好的情况下),就怕慢性病(不知不觉就养成癌症),所以我们程序员要坚持每天运动,不要熬夜啦!

以上就是全部内容啦,如果有你对哪点不清晰或者有问题的话,请在评论下留言,我会尽我所能答复哒

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...