【C++】C\C++内存管理

下面是围绕C\C++内存管理这一块知识谈论相关的内存管理机制,有需要借鉴即可。

同时,我在下面也放了快速建立链表的模板,方便oj题目拿到vs上进行调试。

内存管理目录

  • 1.CPP内存管理
    • 1.1new、delete关键字概念
    • 1.2特性
    • 1.3总结
  • 2.new、delete的底层
    • 2.1new的底层是operator new:
    • 2.2delete的底层是operator delete
    • 2.3总结
  • 3.内存泄漏
    • 3.1概念
  • 4.快速生成链表模板

在介绍本节博客之前,请思考为什么要进行内存划分?或者说内存为什么要划分为不同的区域?直接一整块使用多好。

答案是为了方便内存管理。这就类似于我们为什么要对全国进行划分不同给的省份?正是因为划分了不同的省份可以方便管理才这样做的。
在这里插入图片描述

1.CPP内存管理

针对于C/CPP语言,我们一般将内存划分为如下几个不同的区域:
在这里插入图片描述
注:语言层面名称:静态区、常量区
操作系统层面名称:数据段、代码段

请回答下面代码中的变量分别存储在计算机内存的哪个区域?

int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{static int staticVar = 1;int localVar = 1;int num1[10] = { 1, 2, 3, 4 };char char2[] = "abcd";const char* pChar3 = "abcd";int* ptr1 = (int*)malloc(sizeof(int) * 4);int* ptr2 = (int*)calloc(4, sizeof(int));int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);free(ptr1);free(ptr3);
}

在这里插入图片描述
下面是答案:

在这里插入图片描述

对于上面所介绍的这些内存空间,我们作为编写代码的人应该重点关注哪一块区域呢?
答:
是堆空间,因为堆是系统把一部分操作权限给到我们编写代码的人的,包括一些堆的空间申请,堆的空间释放…

在C语言中,我们常用malloc\realloc\calloc进行对堆空间的申请和free释放
因而想要使用堆空间,下面代码基本说是"必经之路"。

思考:malloc、realloc、calloc的区别?
答:
malloc:申请一块空间
realloc:更改空间大小,支持原地扩容和异地扩容
calloc:申请一块空间并初始化

void Test ()
{
int* p1 = (int*) malloc(sizeof(int));
free(p1);
// 1.malloc/calloc/realloc的区别是什么?
int* p2 = (int*)calloc(4, sizeof (int));
int* p3 = (int*)realloc(p2, sizeof(int)*10);
// 这里需要free(p2)吗?
free(p3 );
}

我们申请一块空间是需要先把地址放到一个指针变量里,然后再进行检查…程序复杂且重复。
CPP为了解决这个问题,通过对malloc函数进行封装加工处理,形成了new关键字,通过对free函数的封装加工处理,形成了delete关键字。

1.1new、delete关键字概念

CPP提供的new与delete相对于C语言中的malloc与free的提升主要集中在两个方面,一是用法更加简单,二是功能更加强大

1.2特性

  • 1.用法上,更加简单

    • new关键字替代了malloc(sizeof())和检查那一大堆
      在这里插入图片描述
  • 2.功能上,更加强大

    • ①开始:可以支持在开辟空间时候初始化
      在这里插入图片描述

    • ②创建过程:可以支持自定义类型的空间开辟,new自动调用构造函数,delete自动调用对应的析构函数(重点)
      在这里插入图片描述

    • ③结束:new失败了会抛异常,不用指针检查是否为空

1.3总结

在这里插入图片描述

从上面看来,new和delete的语法引入大大方便了我们对堆空间的使用。那其底层是如何实现的呢?

2.new、delete的底层

2.1new的底层是operator new:

new —>operator new + n次构造函数(自定义类型) —>malloc
new[] —> operator new[] —> operator new + n次构造函数(自定义类型) —> malloc

我们以下面代码为例,看其汇编解析其底层:
在这里插入图片描述
在这里插入图片描述

思考:为什么要定义operator new对malloc实现封装?
答:
①要实现new失败要抛异常
②要调用自定义类型的构造函数

思考:直接new空间,编译器是怎么确定要开多大空间的?C语言中我们需要给空间大小的。
答:通过sizeof编译时进行计算,sizeof是一种运算符,其在编译期间确定,而不是在运行时。

思考:为什么上面自定义类型开空间多开8个字节的空间?
答:主要是多开几个字节的空间来存储这块空间多大,方便下一步delete释放时候要释放多少空间。
在这里插入图片描述

注:下图蓝色区域是新开空间存储相关内容的空间区域,红色则是存储这块空间是多大的,方便delete的删除操作。
在这里插入图片描述

2.2delete的底层是operator delete

delete —> 析构函数 + operator delete —> free
注意:有些delete[]会进一步调用operator delete

思考:operatr delete是先调用析构函数还是先调用free?
答:先调用析构函数
在这里插入图片描述

创建与销毁一定要对等使用,即:

  • 开辟空间:new[] ,释放空间:delete[]
  • 开辟空间:new,释放空间:delete

思考:为什么?
在这里插入图片描述

2.3总结

在这里插入图片描述

3.内存泄漏

3.1概念

是指一块内存空间申请了不用却也不还给系统。

共分为两种情况:

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

4.快速生成链表模板

#include<iostream>
using namespace std;struct ListNode
{int _val;ListNode* _next;//构造函数初始化ListNode(int val = 0):_val(val), _next(nullptr){}
};ListNode* CreatList(int n)
{ListNode head(-1);//生成一个类对象ListNode* tail = &head;//尾指针int val;printf("请依次输入%d个节点的val值:>\n", n);for (int i = 0; i < n; i++){//cin >> val;val = i;tail->_next = new ListNode(val);tail = tail->_next;}return head._next;
}void test2()
{ListNode* head = CreatList(100);ListNode* pcur = head;for (int i = 0; i < 100; i++){cout << pcur->_val << "  ";pcur = pcur->_next;}
}

EOF

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

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

相关文章

电商API数据采集接口||大数据的发展,带动电子商务产业链,促进了社会的进步

最近几年计算机技术在诸多领域得到了有效的应用&#xff0c;同时在多方面深刻影响着我国经济水平的发展。除此之外&#xff0c;人民群众的日常生活水平也受大数据技术的影响。 主流电商API数据采集接口||在这其中电子商务领域也在大数据技术的支持下&#xff0c;得到了明显的进…

《逃离塔科夫》PVE模式加入付费特别版引发玩家不满

《逃离塔科夫》PVE模式加入付费特别版引发玩家不满 近期&#xff0c;《逃离塔科夫》开发者Battlestate发布了多个新版本&#xff0c;但其中PVE模式只能在价格最高的“Unheard Edition”中购买&#xff0c;导致玩家不满。据悉&#xff0c;“Unheard Edition”售价高达250欧元&a…

Linxu系统服务管理,systemd知识/进程优先级/平均负载/php进程CPU100%怎么解决系列知识!

shell脚本&#xff08;命令&#xff09;放后台 sleep 300& 放到后台运行&#xff0c;脚本或命令要全路径 nohup&#xff1a;用户推出系统进程继续工作 【功能说明】 nohup 命令可以将程序以忽略挂起信号的方式运行起来&#xff0c;被运行程序的输出信息将不会显示到终端 如…

小程序的合同是怎么样写的

​很多商家找第三方做小程序都遭遇到了各种问题&#xff0c;如访问速度慢、服务器关闭、反复收费等。如果当初商家找的是正规的第三方服务商&#xff0c;双方签订了明确的合同条款&#xff0c;出现任何问题后&#xff0c;相信都能够进行解决。下面将具体介绍合同内容&#xff0…

大田场景下的路径检测论文汇总

文章目录 2020Visual Servoing-based Navigation for Monitoring Row-Crop Fields 2020 Visual Servoing-based Navigation for Monitoring Row-Crop Fields code: https://github.com/PRBonn/visual-crop-row-navigation 摘要&#xff1a; 自主导航是野外机器人执行精确农业…

ElasticSearch自动补全

一、拼音分词器&#xff1a; 当用户在搜索框输入字符时&#xff0c;我们应该提示出与该字符有关的搜索项&#xff0c;如图&#xff1a; 这种根据用户输入的字母&#xff0c;提示完整词条的功能&#xff0c;就是自动补全了。 GET /_analyze {"text":"我爱螺蛳粉…

opencv图片绘制图形-------c++

绘制图形 #include <opencv2/opencv.hpp> #include <opencv2/core.hpp> #include <filesystem>bool opencvTool::drawPolygon(std::string image_p, std::vector<cv::Point> points) {cv::Mat ima cv::imread(image_p.c_str()); // 读取图像&#xf…

制造业智慧工厂

在信息化、智能化浪潮的推动下&#xff0c;制造业正迎来一场前所未有的变革。智慧工厂&#xff0c;作为这一变革的核心载体&#xff0c;正逐渐成为制造业发展的新引擎。HiWoo Cloud平台&#xff0c;以其卓越的物联网云技术&#xff0c;为制造业智慧工厂的构建提供了强有力的支持…

Linux逻辑方式合并物理磁盘

在日常生活中&#xff0c;我们总是遇到一个文件太大&#xff0c;以至于我们的两个磁盘都装不下&#xff0c;这时我们就需要将两块物理磁盘逻辑化的连接在一起&#xff0c;把物理磁盘使用逻辑化的方法合并在一起&#xff0c;形成卷组&#xff0c;使得磁盘空间可以公用&#xff1…

【 AIGC 研究最新方向(上)】面向平面、视觉、时尚设计的高可用 AIGC 研究方向总结

目前面向平面、视觉、时尚等设计领域的高可用 AIGC 方向有以下 4 种&#xff1a; 透明图层生成可控生成图像定制化SVG 生成 本篇&#xff08;上篇&#xff09;介绍 1、2&#xff0c;而下篇将介绍 3、4。 透明图层生成 LayerDiffuse 代表性论文&#xff1a;Transparent Imag…

请编写函数fun,该函数的功能是:实现B=A+A‘,即把矩阵A加上A的转置,存放在矩阵B中。计算结果在main函数中输出。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法完整代码和详细的解析。 题干 请编…

redis基础(一)

启动与关闭 启动命令在/usr/local/bin目录 服务端后台启动&#xff1a;redis-server opt/redis-6.2.1/redis.conf 客户端连接&#xff1a;执行 redis-cli 关闭操作 ​ 方式1&#xff1a;进入终端后关闭 ​ 方式2&#xff1a;直接kill 掉进程 方式3&#xff1a;通过实例关闭 …

【力扣周赛】第394场周赛

文章目录 1.统计特殊字母的数量2.使矩阵满足条件的最少操作次数 1.统计特殊字母的数量 题目链接 &#x1f34e;该题涉及的小技巧&#xff1a;&#x1f425; &#x1f427;①大写字母和对应的小写字母低5位都是相等的&#xff1b; &#x1f427;②大写字母ASCII二进制第 6 位…

应用实战|只需几步,即可享有外卖订餐小程序

本示例是一个简单的外卖查看店铺点菜的外卖微信小程序&#xff0c;小程序后端服务使用了MemFire Cloud&#xff0c;其中使用到的MemFire Cloud功能包括&#xff1a; 其中使用到的MemFire Cloud功能包括&#xff1a; 云数据库&#xff1a;存储外卖微信小程序所有数据表的信息。…

实时采集麦克风并播放(springboot+webscoekt+webrtc)

项目技术 springbootwebscoektwebrtc 项目介绍 项目通过前端webrtc采集麦克风声音&#xff0c;通过websocket发送后台&#xff0c;然后处理成g711-alaw字节数据发生给广播UDP并播放。 后台处理项目使用线程池(5个线程)接受webrtc数据并处理g711-alaw字节数组放到Map容器中&…

PotatoPie 4.0 实验教程(26) —— FPGA实现摄像头图像拉普拉斯锐化

为什么要对图像进行拉普拉斯锐化 对图像进行拉普拉斯锐化的目的是增强图像的边缘和细节&#xff0c;使图像看起来更加清晰和锐利。这种技术常用于图像处理中&#xff0c;具体原因如下&#xff1a; 增强图像的边缘信息&#xff1a;拉普拉斯锐化可以突出图像中的边缘特征&#x…

程序不包含适用于入口点的静态Main方法

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

西湖大学赵世钰老师【强化学习的数学原理】学习笔记1节

强化学习的数学原理是由西湖大学赵世钰老师带来的关于RL理论方面的详细课程&#xff0c;本课程深入浅出地介绍了RL的基础原理&#xff0c;前置技能只需要基础的编程能力、概率论以及一部分的高等数学&#xff0c;你听完之后会在大脑里面清晰的勾勒出RL公式推导链条中的每一个部…

数据结构_时间复杂度

✨✨所属专栏&#xff1a;数据结构✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 什么是时间复杂度&#xff1f; 时间复杂度的定义&#xff1a;在计算机科学中&#xff0c;算法的时间复杂度是一个函数&#xff0c;它定量描述了该算法的运行时间。一个算法执行所耗费的时间&#xff0…

【go零基础】go-zero从零基础学习到实战教程 - 0环境配置

是个前端&#xff0c;最近开始学习go&#xff0c;后端除node外基本0基础&#xff0c;所以学习曲线有点绕&#xff0c;目标是个基础的服务端demo&#xff0c;搞个api服务后台&#xff0c;包含基础的用户登录、文章发布和写文章、权限控制&#xff0c;差不多就是个完整博客系统。…