c++ - 空间申请和释放 new/delete

文章目录

    • 一、c/c++内存分布
    • 二、new/delete 的使用
    • 三、malloc/free 和 new/delete 的对比
    • 四、new/delete 的实现原理
    • 五、匹配问题


一、c/c++内存分布

求下面各个变量的位置

// c/c++内存分布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.代码段(常量区)  

1、 globalVar在哪里?____ 2、staticGlobalVar在哪里?____ 3、staticVar在哪里?____ 4、localVar在哪里?____ 5、num1 在哪里?____ 6、char2在哪里?____ 7、*char2在哪里?___ 8、pChar3在哪里?____ 9、*pChar3在哪里?____ 10、ptr1在哪里?____ 11、*ptr1在哪里?____
答案:1-5 CCCAA 6-11AAADAB

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4ea571fe70e04481baf829bd12b580aa.png

说明:

  1. 栈又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的。
  2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口 创建共享共享内存,做进程间通信。(Linux课程如果没学到这块,现在只需要了解一下)
  3. 堆用于程序运行时动态内存分配,堆是可以上增长的。
  4. 数据段–存储全局数据和静态数据。
  5. 代码段–可执行的代码/只读常量。

二、new/delete 的使用

关键字: new
作用:申请空间
关键字:delete
作用:释放空间

如:


//new 和 delete的使用
int main()
{//new 申请一个变量空间	int* p = new int;	//(类型指针) 指针名 = new 类型//delete 释放一个变量空间	// delete 释放的指针delete p;//new 申请一个数组空间	int* pp = new int[10];	//(类型指针) 指针名 = new 类型[(申请的数组大小)]//delete 释放一块数组的空间delete[]pp;	//delete [] 释放的指针return 0;
}

注意:
释放数组的时候 delete 一定要和 [ ] 配对使用,不然只会释放该指针指向的第一个位置,这样就会造成内存泄漏。

三、malloc/free 和 new/delete 的对比

1、mallocfree是库函数,而newdelete是运算符(类似sizeof 属于运算符而不属于库函数) 。

2、malloc使用比new更复杂
如:

int main()
{//malloc申请一个变量空间int* p = (int*)malloc(sizeof(int));//new申请一个变量空间int* pp = new int;return 0;
}

在这里插入图片描述

3、malloc 不能对申请的空间进行初始化,而 new
如:

int main()
{//对一个变量初始化int* p = new int(10);	//在后面加括号再加初始化的值//对数组进行初始化int* pp = new int[5] {1, 2, 3, 4, 5};	//在后面加花括号再加初始化的值cout << *p << endl;for (int i = 0; i < 5; i++){cout << pp[i] << " ";}return 0;
}

在这里插入图片描述

4、对于自定义类型,new能调用其构造函数,delete能调用其析构函数,而malloc/free不行。

如:

class A
{
public:A(){cout << "A()" << endl;}~A(){cout << "~A()" << endl;}
};int main()
{//用malloc申请A* a = (A*)malloc(sizeof(A));free(a);cout << "划分线" << endl;//用new申请一个自定义类型空间A* p = new A;//用new申请一个自定义类型数组A* pp = new A[10];//释放delete p;delete[]pp;return 0;
}

在这里插入图片描述

5、在申请空间失败时malloc会返回NULL,而new则会抛出异常。

四、new/delete 的实现原理

operator new 函数(底层还是使用malloc申请空间)是 new 的底层实现。
operator delete 函数(底层还是使用free释放空间)是 delete 的底层实现。
operator new[] 函数是 new 类型[ ]的实现。
operator delete[] 函数是 delete[] 的实现。

对于内置类型

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

对于自定义类型

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

练习1
使用 char* p = new char[100]申请一段内存,然后使用delete p释放,有什么问题?( )
A.会有内存泄露
B.不会有内存泄露,但不建议用
C.编译就会报错,必须使用delete []p
D.编译没问题,运行会直接崩溃
答案:B

A.对于内置类型,此时delete就相当于free,因此不会造成内存泄漏
B.正确
C.编译不会报错,建议针对数组释放使用delete[],如果是自定义类型,不使用方括号就会运行时错误
D.对于内置类型,程序不会崩溃,但不建议这样使用

练习2
ClassA *pclassa=new ClassA[5];delete pclassa;c++语言中,类ClassA的构造函数和析构函数的执行次数分别为( )
A.5,1
B.1,1
C.5,5
D.程序可能崩溃
答案:D

A.申请对象数组,会调用构造函数5次,delete由于没有使用[],此时只会调用一次析构函数,但往往会引发程序崩溃
B.构造函数会调用5次
C.析构函数此时只会调用1次,要想完整释放数组空间,需要使用[]
D.正确

五、匹配问题

关于malloc/free 和 new/delete 申请和释放匹配

1、对于内置类型,是可以的,但是不建议,最好还是配对使用

//内置类型
int main()
{	//new 申请int* p = new int;//free 释放free(p);//malloc 申请int* pp = (int*)malloc(sizeof(int));//delete 释放delete pp;return 0;
}

会报警告:
在这里插入图片描述
在这里插入图片描述

2、对于自定义类型来说很容易出现问题,如下面

(1)申请数组

class A
{
public:A():_a(10){cout << "A()" << endl;}~A(){cout << "~A()" << endl;}
private:int _a;
};int main()
{cout << sizeof(A) << endl;	//大小为 4// 用 malloc 申请 申请空间的大小为 80字节A* pp = (A*)malloc(sizeof(A) * 20);//用 new  申请  申请的空间大小为 88字节(原本是应为 80 字节,但是多出来的8字节为保存申请多少个A )A* p = new A[20];	//用 free 释放free(p);	//直接崩掉,因为p的地址为申请的88个字节中的第8个字节地址,所以有8字节无法释放并且无法调用析构//用delete 释放delete [] pp;	//因为不知道应该析构多少个A(用new会保存申请了多少个A,这时delete就会知道)// ,所以出现死循环析构return 0;
}

new A[20] 申请需要的字节
在这里插入图片描述
在这里插入图片描述

malloc(sizeof(A) * 20) 申请需要的字节

在这里插入图片描述

(2)申请一个自定义类型

//申请一个自定义类型
// 用 malloc 申请 申请空间的大小为 4字节  
A* pp = (A*)malloc(sizeof(A));	//少了构造//用delete释放  
delete pp;	//可以但是不建议用 new  申请  申请的空间大小为 4 字节
A* p = new A;	free(p);	//不会报错,少了析构,当自定义类型里有需要释放的资源是就会出现内存泄漏

(3)总结:
尽量不要用这种不配对的情况,不然可能会出现各种各样的问题,最好配对使用,这样才能保证程序不会在这方面出错。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

前端零代码开发实践:页面嵌套+逻辑连线0开发扩展组件,实现切换开关控制扇叶转动。能无代码封装扩展组件,有别于常规的web组态或低代码平台

前言&#xff1a; 官网:http://www.uiotos.net/ 什么是 UIOTOS&#xff1f; 这是一款拥有独创专利技术的前端零代码工具&#xff0c;专注于解决前端界面开发定制难题&#xff0c;原型即应用&#xff01;具有页面嵌套、属性继承、节点连线等全新特性&#xff0c;学习门槛低…

敷尔佳2023年报前瞻:“医美面膜第一股”的护城河及2024展望

查理芒格曾说&#xff1a;“要去鱼多的地方打渔”。历数长线牛股辈出的领域&#xff0c;消费行业无疑是大赢家。此中&#xff0c;美业又是消费行业最好的细分赛道之一。 4月26日&#xff0c;A股“医美面膜第一股”–敷尔佳(SZ:301371)将发布2023年财报&#xff0c;按惯例对本季…

ros2_control【B站WMGIII教学学习记录】1

资源 https://www.bilibili.com/video/BV1ku411G7UR? 学习过程中存在bug&#xff0c;记录一下 1 Q:"package ‘joint_state_publisher_gui’ not found, searching: [/home A: sudo apt install ros-humble-joint-state-publisher2 https://fishros.org.cn/forum/to…

蓄能勃发,酷开科技携酷开系统“软硬结合”提升大屏实力

智慧大屏以全新媒体形态之姿在过去几年快速增长&#xff0c;截至去年上半年&#xff0c;国内联网电视总量覆盖达5.26亿&#xff0c;其中智能电视终端活跃量达3.22亿&#xff0c;在PC、Mobile流量增长已显疲态的背景下&#xff0c;大屏的高速发展意味着一个新的赛道的崛起&#…

保护你的网站:了解5种常见网络攻击类型及其防御方法

随着互联网的迅猛发展&#xff0c;针对网站的各种类型的网络攻击随之增加&#xff0c;网络攻击事件层出不穷&#xff0c;由此&#xff0c;如何保护网站安全成为每个网站所有者的重要议题。在下面的内容中&#xff0c;我们将探讨5种常见网络攻击类型及其防御方法&#xff0c;以帮…

Linux中手工创建一个用户

当我们需要新创建一个用户时&#xff0c;有两种方法 1&#xff0c;使用useradd命令&#xff1a; [rootlocalhost /]# useradd tmg 然后给它设置一个密码 [rootlocalhost etc]# passwd tmg Changing password for user tmg. New password: BAD PASSWORD: The password is a…

C++ | Leetcode C++题解之第46题全排列

题目&#xff1a; 题解&#xff1a; class Solution { public:void backtrack(vector<vector<int>>& res, vector<int>& output, int first, int len){// 所有数都填完了if (first len) {res.emplace_back(output);return;}for (int i first; i &…

【大语言模型LLM】-基础语言模型和指令微调的语言模型

&#x1f525;博客主页&#xff1a;西瓜WiFi &#x1f3a5;系列专栏&#xff1a;《大语言模型》 很多非常有趣的模型&#xff0c;值得收藏&#xff0c;满足大家的收集癖&#xff01; 如果觉得有用&#xff0c;请三连&#x1f44d;⭐❤️&#xff0c;谢谢&#xff01; 长期不…

【古琴】倪诗韵古琴雷修系列(形制挺多的)

雷音系列雷修&#xff1a;“修”字取意善、美好的&#xff0c;更有“使之完美”之意。精品桐木或普通杉木制&#xff0c;栗壳色&#xff0c;纯鹿角霜生漆工艺。 方形龙池凤沼。红木配件&#xff0c;龙池上方有“倪诗韵”亲笔签名&#xff0c;凤沼下方&#xff0c;雁足上方居中位…

微软开源phi-3-mini体验地址;将你的想法转换成代码,并从中构建出代码原型jemma

✨ 1: Lumina-T2X 基于文本的多功能生成模型 Lumina-T2X 是一种基于文本的多功能生成模型&#xff0c;能够根据文字指令&#xff0c;将噪声数据转化为图片、视频、3D对象的多视图图片以及语音。这个技术利用一种被称为流式大扩散变换器&#xff08;Flow-based Large Diffusio…

2024的新宠儿——Mamba(1):SSM

引言 自 2017 年被提出以来,Transformer 已经成为 AI 大模型的主流架构,但随着模型规模的扩展和需要处理的序列不断变长,Transformer 的局限性也逐渐凸显。一个很明显的缺陷是:Transformer 模型中自注意力机制的计算量会随着上下文长度的增加呈平方级增长,比如上下文增加 …

linux autogroup

一&#xff1a;概述 对于linux autogroup的作用&#xff0c;很多同学可能是听说过&#xff0c;但&#xff0c;并未验证过。 考虑下面场景&#xff0c;开两个terminal&#xff0c;T1和T2&#xff0c;在T1中运行进程P1&#xff0c;P1开启9个线程编译代码&#xff0c;在T2中运行…

uniapp引入uniapp打包的H5跳转H5以及H5返回app方法

在app项目添加webview文件夹添加gridWebview.vue文件。代码如下 <template><view><web-view :src"src" message"getMessage" ></web-view></view> </template><script>export default {data() {return {src: ,…

Python中pyside2出现的pyside2 qt platform plugin could be in错误及其解决方法

系统平台&#xff1a;Win10 64bit python版本&#xff1a; python 3.8 使用pip install pyside2安装 pyside2 这是找不到QT平台的插件&#xff0c;这是环境变量QT_QPA_PLATFORM_PLUGIN_PATH出现错误 具体解决方法&#xff1a; 我们可以在每一段程序开始之前设定环境变量&…

设备需要支持GMS,Rockchip芯片,写入Attestation key方法 Google 申请keybox 检查是否已经写入Attestation key

写入Attestation key方法 首先通过3PL向谷歌申请Google keybox&#xff0c;拿到keybox后使用瑞芯微提供的打包工具 rkpacker打包成烧写的格式&#xff0c;再使用工具烧写到设备中&#xff0c;相关的工具在工程目录 1、申请Google keybox 比如test_keybox.xml 2、打包工具Lin…

MySQL多版本并发控制mvcc原理浅析

文章目录 1.mvcc简介1.1mvcc定义1.2mvcc解决的问题1.3当前读与快照读 2.mvcc原理2.1隐藏字段2.2版本链2.3ReadView2.4读视图生成原则 3.rc和rr隔离级别下mvcc的不同 1.mvcc简介 1.1mvcc定义 mvcc(Multi Version Concurrency Control)&#xff0c;多版本并发控制&#xff0c;是…

uniapp实现点击事件跳转页面

首先定义一个点击事件 这里采用的vue3的写法&#xff0c;然后写上触发事件后要跳转的路径 function jump() {uni.switchTab({url:/pages/bangong/index})} 到这里就简单的实现uniapp的点击跳转页面了

IIS部署跨平台.Net Core项目

IIS部署跨平台.Net Core项目 文章介绍: 大家好,我是行不更名,坐不改姓的宋晓刚,下面是IIS部署跨平台.Net Core项目的教程。 微信:15319589104 QQ: 2981345658 1.0我们部署的项目为.Net Core项目 2.0打开IIS管理器 3.0设置控制面板中的参数,程序 》程序和功能 》启用和…

如何用PHP语言实现远程语音播报

如何用PHP语言实现远程语音播报呢&#xff1f; 本文描述了使用PHP语言调用HTTP接口&#xff0c;实现语音播报。通过发送文本信息&#xff0c;来实现远程语音播报、语音提醒、语音警报等。 可选用产品&#xff1a;可根据实际场景需求&#xff0c;选择对应的规格 序号设备名称1…

电脑虚拟机有免费的吗?常见的虚拟机工具软件有哪些?Parallels Desktop19最新版本好用吗

PD虚拟机&#xff0c;即Parallels Desktop&#xff0c;是一款专为Mac用户设计的虚拟机软件&#xff0c;由Parallels公司开发&#xff0c;它允许用户在Mac操作系统上无缝运行Windows、Linux以及其他操作系统&#xff0c;并在这些系统中安装程序或者游戏&#xff0c;无需重启即可…