【C++】---内存管理new和delete详解
一、C/C++内存分布
C/C++内存被分为6个区域:
(1) 内核空间:存放内核代码和环境变量。
(2)栈区:向下增长(存放非静态局部变量,函数参数,返回值等等)
(3)内存映射段:文件映射,匿名映射,动态库。
(4)堆区:向上增长(用于程序运行时动态内存的分配)
(5)数据段:也叫,静态区/全局域,(存放全局变量和静态变量)
(6)代码段:也叫常量区,(存放可读代码和只读常量)
看看下面代码的例题:
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);
}
-
选择题:
选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
globalVar在哪里?____ staticGlobalVar在哪里?____
staticVar在哪里?____ localVar在哪里?____
num1 在哪里?____char2在哪里?____ *char2在哪里?___
pChar3在哪里?____ *pChar3在哪里?____
ptr1在哪里?____ *ptr1在哪里?____ -
填空题:
sizeof(num1) = ____;
sizeof(char2) = ____; strlen(char2) = ____;
sizeof(pChar3) = ____; strlen(pChar3) = ____;
sizeof(ptr1) = ____;- sizeof 和 strlen 区别?
1.C C C A A
2. A A A D A B
3.40 5 4 4或8 4 4或8
3.sizeof和strlen的区别:
(1)char ch2[ ]=“abcd”; // sizeof(ch2)=5 (因为末尾还有一个’\0’)
// strlen(ch2)=4 (因为strlen其他都不管,遇到’\0’就结束,‘\0’不计入)
(2)sizeof()内部要看变量是否为指针,若是指针==4/8
strlen不看变量是否为指针,只看’\0’ ,遇到’\0’结束为止!!!
4.对char2,pchar3,ptr1的解释:
(1)字符串存在于常量区,当拿来初始化char2的时候,char2会在栈区开辟一个空间,然后再把字符串拷贝给char2,char2就在栈区。
(2)char2是数组名,对地址解引用,*char2仍然在栈区!
(3) 被const的修饰变量不一定在常量区,有可能const修饰的是常变量,存放在栈区!
(4)pchar3是在栈上的指针变量,*pchar3=='‘abcd\0’'是:指向的字符串“abcd\0”存放在常量区
(5)ptr1是在栈上的指针变量,ptr1由于是由malloc出来的,所以ptr1指向的空间(即:*ptr1)在堆区
二、C/C++使用new和delete的原因
new和delete是C++向内存申请空间和释放空间的操作符, C++为什么要使用new和delete?
1.C语言使用malloc、calloc、realloc、free管理的不便之处在于:
(1)需要手动申请空间,手动计算申请的字节大小。
(2)对返回值void*需要进行强转,否则无法进行解引用。
(3)内存申请是否成功还需要进行判断。
(4)需要include头文件<stdlib.h>
2.new和delete对自定义类型也会进行处理:
(1)new会调用构造函数对类对象进行初始化
(2)delete会调用析构函数进行资源清理
三、C++动态管理内存的方式
1.new和delete
(1)new/delete和malloc/free对内置类型的操作没有区别
注意:
①申请和释放单个空间,需要用new和delete。
②申请和释放多个空间,需要用new [ ]和delete [ ]
(2)new的特点:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;int main()
{// 1.C语言申请空间int* p0 = (int*)malloc(sizeof(int) * 4);if (p0 == NULL){perror("malloc fail");return 1;}free(p0);// 2.new 1个int整型的元素int* p1 = new int;delete p1;// 3.new 10个int整型元素,(即:数组)int* p2 = new int[10];// 申请的时候为:new[ ] ,释放的时候,必须要用delete[ ] delete[] p2;// 4.可以控制初始化int* p3 = new int(10); // new一个int整型 并且初始化为10delete p3;// 5.new失败后会抛异常,不必手动检查
}
C++11开始支持new初始化数组:
如果没有初始化到的,默认为0
int* p4 = new int[10] {1, 2, 3, 4, 5};
delete[] p4;
(3)new/delete和malloc/free对自定义类型的操作有区别:
①malloc/free对自定义类型的操作只会开空间/释放空间
②new操作自定义类型会开空间+构造函数初始化,delete操作自定义类型会调用析构函数清理+释放空间
class ListNode
{
public:ListNode* _prev;ListNode* _next;int _val ;ListNode():_prev(nullptr),_next(nullptr),_val(0){cout << "this _val=" << _val << endl;}~ListNode(){cout << "~ListNode()" << endl;}
};int main()
{ListNode* p1 = (ListNode*)malloc(sizeof(ListNode) * 4);ListNode* p2 = new ListNode;free(p1);delete(p2);return 0;
}
当程序走完第94行之后,那么p2里面的值都被初始化了。然而对于93行malloc出来的值都是随机值。从调试的界面可以看出,它也调用了构造函数,所以打印出:this _val=0
这就是new和malloc的区别,new对自定义类型会调用构造函数(delete会调用析构函数),对对象进行初始化和空间清理,而C语言之前的malloc和free不会这样做,他们只会开辟空间和释放空间。
2.operator new和operator delete
(1)定义:operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,(operator new是对malloc的封装),delete在底层通过operator delete全局函数来释放空间,(operator delete是对free的封装)它们不是new和delete的重载。
(2)与malloc区别:operator new、operator delete的用法和malloc、free的用法是一样的,功能都是在堆上申请释放空间,但是失败了的处理方式不一样,malloc失败返回NULL,operator new失败以后抛异常。
使用new为自定义类型ListNode申请空间并初始化:new会调用operator new函数和构造函数,operator new会调用malloc和失败抛异常机制,因此new和operator new申请失败都会抛异常:
从上图可以看出,new并不直接调用 malloc,而是调用了operator new,因为operator new被封装了,malloc申请失败直接报返回值,但operator new申请失败会抛异常
总结:
对于自定义类型来说:(只有自定义类型才有构造和析构,内置类型不存在的)
(1)new—>operator new<—>malloc+构造函数
(2)delete—>析构函数+operator delete<—>free 注意两者的顺序不同
3.总结
malloc/free和new/delete总结:
(1)malloc/free是函数,new/delete是操作符
(2)malloc申请的空间不会初始化,new可以初始化
(3)malloc申请的空间需要手动计算并传递过去,而new只需要在后面跟上空间类型即可。
(4)new不需要强转,而malloc需要
(5)malloc申请空间之后需要判断是否申请失败,new不需要,但是new需要捕获异常
(6)申请自定义类型对象时,malloc/free只会开辟空间,而new在申请空间 后会调用构造函数完成对象的初始化,delete在释放空间 前 会调用析构函数完成空间中资源的清理。
五、内存泄漏
1.定义:内存泄漏的概念:一块已经不用的空间,没有释放
2.危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会 导致响应越来越慢,最终卡死。
3.有关内存泄漏的例题
class A
{
public:A(){cout << "A()" << endl;}~A(){cout << "~A()" << endl;}
};int main()
{A* a = new A[5];//delete a; 内存泄漏,只释放了1次delete[] a;return 0;
}
关键点:(记住:一定要匹配使用,如若违背结果将不确定!)
new—>delete
new[ ] —>delete[ ]
好了,今天的分享就到这里了
如果对你有帮助,记得点赞👍+关注哦!
我的主页还有其他文章,欢迎学习指点。关注我,让我们一起学习,一起成长吧!
相关文章:

【C++】---内存管理new和delete详解
一、C/C内存分布 C/C内存被分为6个区域: (1) 内核空间:存放内核代码和环境变量。 (2)栈区:向下增长(存放非静态局部变量,函数参数,返回值等等) …...

go-zero微服务入门教程
go-zero微服务入门教程 本教程主要模拟实现用户注册和用户信息查询两个接口。 准备工作 安装基础环境 安装etcd, mysql,redis,建议采用docker安装。 MySQL安装好之后,新建数据库dsms_admin,并新建表sys_user&#…...
蓝桥杯刷题--python-12
3768. 字符串删减 - AcWing题库 nint(input()) sinput() res0 i0 while(i<n): if s[i]x: ji1 while(j<n and s[j]x): j1 resmax(j-i-2,0) ij else: i1 print(res) 3777. 砖块 - AcWing题库 # https://www.a…...

LeetCode LCR 085.括号生成
正整数 n 代表生成括号的对数,请设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 示例 1: 输入:n 3 输出:[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”] 示例 2: 输入&#x…...

抖音视频评论数据提取软件|抖音数据抓取工具
一、开发背景: 在业务需求中,我们经常需要下载抖音视频。然而,在网上找到的视频通常只能通过逐个复制链接的方式进行抓取和下载,这种操作非常耗时。我们希望能够通过关键词自动批量抓取并选择性地下载抖音视频。因此,为…...

【web】云导航项目部署及环境搭建(复杂)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、项目介绍1.1项目环境架构LNMP1.2项目代码说明 二、项目环境搭建2.1 Nginx安装2.2 php安装2.3 nginx配置和php配置2.3.1 修改nginx文件2.3.2 修改vim /etc/p…...
软件测试人员必会的linux命令
文件和目录操作: ● ls:列出目录中的文件和子目录。 ● cd:改变当前工作目录。 ● mkdir:创建新目录。 ● rm:删除文件或目录。 ● cp:复制文件或目录。 ● mv:移动或重命名文件或目录。 文本查看和编辑: ● cat:查看文件内容。 ● more或less:分页查看文件内…...

Mac使用K6工具压测WebSocket
commend空格 打开终端,安装k6 brew install k6验证是否安装成功 k6 version设置日志级别为debug export K6_LOG_LEVELdebug执行脚本(进入脚本所在文件夹下) k6 run --vus 100 --duration 10m --out csvresult.csv script.js 脚本解释&…...

小程序--vscode配置
要在vscode里开发微信小程序,需要安装以下两个插件: 安装后,即可使用vscode开发微信小程序。 注:若要实现鼠标悬浮提示,则需新建jsconfig.json文件,并进行配置,即可实现。 jsconfig.json内容如…...

linux僵尸进程
僵尸进程(Zombie Process)是指在一个进程终止时,其父进程尚未调用wait()或waitpid()函数来获取该进程的终止状态信息,导致进程的资源(如进程表中的记录)仍然保留在系统中的一种状态。 当一个进程结束时&am…...
【web | CTF】攻防世界 Web_php_unserialize
天命:这条反序列化题目也是比较特别,里面的漏洞知识点,在现在的php都被修复了 天命:而且这次反序列化的字符串数量跟其他题目不一样 <?php class Demo { // 初始化给变量内容,也就是当前文件,高亮显示…...

Vue3中的select 的option是多余的?
背景: 通过Vue3中填充一个下拉框,在打开页面时要指定默认选中,并在选项改变时把下拉框的选中值显示出来 问题: 填充通常的作法是设置 <option v-for"option in cities" :value"option.value" >&a…...

考研408深度分析+全年规划
408确实很难,他的难分两方面 一方面是408本身的复习难度,我们都知道,408的考察科目有四科,分别是数据结构,计算机组成原理,操作系统和计算机网络。大家回想一下自己在大学本科时候学习这些专业课的难度&am…...
【算法笔记】ch01_01_0771 宝石与石头
笔记介绍: 本项目是datawhale发布的LeetCode 算法笔记(Leetcode-Notes)课程完成笔记,根据推荐题目循序渐进练习算法题目。主要用python进行书写相关代码,会介绍解题思路及跑通解法。 0771. 宝石与石头 题目大意 描…...

jQuery瀑布流画廊,瀑布流动态加载
jQuery瀑布流画廊,瀑布流动态加载 效果展示 手机布局 jQuery瀑布流动态加载 HTML代码片段 <!-- mediabanner --><div class"mediabanner"><img src"img/mediabanner.jpg" class"bg"/><div class"text&qu…...

玩转ChatGPT:参考文献速查
一、写在前面 各位大佬,我又回来了,最近2月太忙啦(过年、奶娃、本子、材料、结题),断更了。现水一篇证明我还活着!!! 最近在写国自然本子,遇到一个估计大家都会遇到的问…...

[设计模式Java实现附plantuml源码~行为型]算法的封装与切换——策略模式
前言: 为什么之前写过Golang 版的设计模式,还在重新写Java 版? 答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。 为什么类图要附上uml 因为很…...

【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解】
欢迎来CILMY23的博客喔,本期系列为【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解】,图文讲解各种字符串函数,带大家更深刻理解C语言中各种字符串函数的应用&am…...

如何实现一个K8S DevicePlugin?
什么是device plugin k8s允许限制容器对资源的使用,比如CPU和内存,并以此作为调度的依据。 当其他非官方支持的设备类型需要参与到k8s的工作流程中时,就需要实现一个device plugin。 Kubernetes提供了一个设备插件框架,你可以用…...

Android LruCache源码分析
文章目录 Android LruCache源码分析概述LruCache和LinkedHashMap关系源码分析属性写入数据读取数据删除缓存 Android LruCache源码分析 概述 LruCache(Least Recently Used Cache,最近最少使用缓存)是 Android 中的一种缓存机制。 根据数据…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...