【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 中的一种缓存机制。 根据数据…...
如何使用Inno Setup制作Unity构建程序的Windows安装程序
1. 准备 (1)准备好Unity构建的程序集合 必须包括: Data文件夹(xxx_Data) Mono文件夹(MonoBleedingEdge) 打包的应用程序文件(xxx.exe) Unity播放器dll文件ÿ…...
linux 面试题
1.linux操作系统的常用指令可以详细说下吗,平常哪些用的比较多 文件目录操作命令: ls cd more cat tail mkdir touch rm rmdir 拷贝复制: cp mv 打包解包压缩解压: tar -z 解亚压缩 -c 打包 -x 解包 -v 显示过程 -f 指定文件名 文本编辑: vi vim 查找: find 查找文件 gre…...
嵌入式中逻辑分析仪基本操作方法
前期准备 1.一块能触摸的屏对应的主板机 2.逻辑分析仪对应的软件工具 3.对应的拓展板 4.确定拓展板的引脚分布情况 第一步:逻辑分析仪j基本操作 1.数据捕捉需要先进行对应软件安装,并按照需求进行配置 2.这里以A20为例:此手机使用显示驱动芯片CST148,触摸屏分辨…...
ONLYOFFICE 桌面编辑器 v8.0 更新内容详细攻略
文章目录 引言PDF 表单RTL 支持电子表格中的新增功能Moodle 集成用密码保护 PDF 文件从“开始”菜单快速创建文档本地界面主题下载安装桌面编辑工具总结 引言 官网链接: ONLYOFFICE 官方网址 ONLYOFFICE 桌面编辑器是一款免费的文档处理软件,适用于 Li…...
2024-2-22 作业
作业要求: 复习前面知识点(指针、结构体、函数)整理思维导图顺序表(按位置插入、按位置删除和去重、重新写)理解链表的代码,尝试写一下链表的尾插和输出 1.复习前面知识点(指针、结构体、函数) 2.整理思维导图 3.顺序表(按位置插入、按位置删除和去重、…...
2.1 RK3399项目开发实录-升级固件介绍(物联技术666)
1. 介绍 1.1. 前言 AIO-3399J 出厂默认安装Android操作系统,如果用户要运行其他操作系统,需要使用对应的固件烧写到主板。 AIO-3399J 有灵活的启动方式。一般情况下,除非硬件损坏,AIO-3399J 开发板是不会变砖的。 如果在升级过…...
Uniapp + VUE3.0 实现双向滑块视频裁剪效果
效果图 <template><view v-if"info" class"all"><video:src"info.videoUrl"class"video" id"video" :controls"true" object-fit"fill" :show-fullscreen-btn"false"play-btn…...
【算法小讲堂】#1 贪心算法
引入——关于贪心算法 我们先来做一个小游戏——现在假设自己是一个小偷,桌上有一些物品,包括一台iPhone15、一个充电宝、一个眼罩和一个溜溜梅。此时,你听说警察即将到来,那么你会先带走哪个东西呢? 一般来讲…...
判断当前shell版本
查看$SHELL环境变量: echo $SHELL输出的结果将是当前使用的shell的路径。例如,如果输出为 /bin/bash,则表示当前使用的是Bash shell。 查看ps命令输出: ps -p $$上述命令将显示当前终端进程的信息,其中 $$ 代表当前进…...
如何实现两个电脑之间通过以太网(网线)实现文件互传
如何实现两个电脑之间通过以太网(网线)实现文件互传 本帖目的:介绍如何通过以太网(网线)连接两台电脑,通过文件夹共享的方式,实现两台电脑之间的文件互传。 本帖以笔者实际工作上遇到的场景为例…...
雅虎网站收录提交入口/千锋教育的口碑怎么样
为什么80%的码农都做不了架构师?>>> 微服务需要考虑的几点内容, :) 团队规模 团队成员能否围坐在一张桌边? Yes! -- 你可能不需要微服务 好文档和好设计可以轻易解决部署等运维操作中遇到的挑战。而微服务要解决的问题你还没有遇…...
海兴贴吧/网络seo是什么意思
页面级别的数据传输-Page level data transfer(钉钉)weex to weex 通过URL传参数(携带的数据量有限),通过weex storage moduleweex to h5,h5 to weex 通过URL传参数native to weex 通过alloc weex 容器中的…...
wordpress显示指定分类目录/宁波seo外包推广软件
前段时间组织优化我们的原生模块 API(iOS、Android 模块封装成 JavaScript 接口),于是学习了几篇 JavaScript API 设计的文章,尽管是旧文,但受益匪浅,这里记录一下。 好的 API 设计:在自描述的同…...
wordpress手机自适应/上海seo关键词优化
2019年电商行业发生了诸多变化,体现在:社群运营、私域流量、多渠道会员通三个关键词,即所谓的“私域会员”,无论对于品牌商还是对于中小电商卖家来说“私域会员体系”已经越来越重要了,重要到如果缺了它,后…...
网站建设公司比较/seo系统培训班
第五章 泛型 23、 请不要在新代码中使用原生态类型 声明中具有一个或者多个类型参数的类或者接口,就是泛型类或者泛型接口。泛型类和接口统称为泛型。 每种泛型可以定义一种参数化的类型,格式为:先是类或者接口的名称,接…...
网站建设需要具备什么条件/潍坊网站建设
听说emlog更新到6.0了,下载了一份最新的代码,发现原来的bug还是没有修复。可能是官方没有在意,所以这里简单叙述一下危害。出现的地方在admin/data.php139行if ($action dell_all_bak) {if (!isset($_POST[bak])) {emDirect(./data.php?err…...