【C++】内存管理(new与delete)

这篇具有很好参考价值的文章主要介绍了【C++】内存管理(new与delete)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【C++】内存管理(new与delete),C++,c++,开发语言,学习

👀樊梓慕:个人主页

 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》

🌝每一个不曾起舞的日子,都是对生命的辜负


前言

本篇文章我们一起来学习C++的内存管理方式,实际上C++与C语言的内存管理模式是十分相似的,他们的内存分布完全一致,C语言所学习的内存管理函数在C++中仍然适用,而new与delete的产生主观上认为是为了解决自定义类型的内存管理。


欢迎大家📂收藏📂以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。

=========================================================================

GITEE相关代码:🌟fanfei_c的仓库🌟

=========================================================================


1.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);
}
//1. 选择题:
//选项 : A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
//globalVar在哪里?____ staticGlobalVar在哪里?____
//staticVar在哪里?____ localVar在哪里?____
//num1 在哪里?____
//char2在哪里?____ * char2在哪里?___
//pChar3在哪里?____ * pChar3在哪里?____
//ptr1在哪里?____ * ptr1在哪里?____
//2. 填空题:
//sizeof(num1) = ____;
//sizeof(char2) = ____; strlen(char2) = ____;
//sizeof(pChar3) = ____; strlen(pChar3) = ____;
//sizeof(ptr1) = ____;
//3. sizeof 和 strlen 区别?

 答案:

1. 选择题:

  选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)

  globalVar在哪里?__C__  staticGlobalVar在哪里?__C__

  staticVar在哪里?__C__  localVar在哪里?__A__

  num1 在哪里?__A__

  分析:

  globalVar全局变量在数据段 staticGlobalVar静态全局变量在静态区

  staticVar静态局部变量在静态区  localVar局部变量在栈区

  num1局部变量在栈区

  char2在哪里?__A__  *char2在哪里?__A__

  pChar3在哪里?__A__   *pChar3在哪里?__D__

  ptr1在哪里?__A__    *ptr1在哪里?__B__

  分析:

  char2局部变量在栈区  

  char2是一个数组,把后面常量串拷贝过来到数组中,数组在栈上,所以*char2在栈上

  pChar3局部变量在栈区   *pChar3得到的是字符串常量字符在代码段

  ptr1局部变量在栈区     *ptr1得到的是动态申请空间的数据在堆区

2. 填空题:

  sizeof(num1) = __40__;//数组大小,10个整形数据一共40字节

  sizeof(char2) = __5__;//包括\0的空间

  strlen(char2) = __4__;//不包括\0的长度

  sizeof(pChar3) = __4__;//pChar3为指针

  strlen(pChar3) = __4__;//字符串“abcd”的长度,不包括\0的长度

  sizeof(ptr1) = __4__;//ptr1是指针

全局变量和在全局定义的静态变量的区别:

  • 最主要的区别在于链接属性不同,static修饰的全局变量只在当前文件可用,而全局变量其他文件也可以使用。

说明:

  1. 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的,栈空间由系统分配,但可以通过函数alloca进行动态分配,不过注意,所分配空间不能通过free或delete进行释放。
  2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。(了解)
  3. 堆用于程序运行时动态内存分配,堆是可以上增长的,堆只能动态分配,不能静态分配
  4. 数据段--存储全局数据和静态数据。
  5. 代码段--可执行的代码/只读常量

🔎做几道小题🔍

【C++】内存管理(new与delete),C++,c++,开发语言,学习


分析:

A.栈区主要存在局部变量和函数参数,其空间的管理由编译器自动完成,无需手动控制,堆区是自己申请的空间,在不需  要时需要手动释放

B.栈区先定义的变量放到栈底,地址高,后定义的变量放到栈顶,地址低,因此是向下生长的,堆区则相反

C.频繁的申请空间和释放空间,容易造成内存碎片,甚至内存泄漏,栈区由于是自动管理,不存在此问题

D.32位系统下,最大的访问内存空间为4G,所以不可能把所有的内存空间当做堆内存使用,故错误

答案:D 


【C++】内存管理(new与delete),C++,c++,开发语言,学习


分析: 

A.堆大小受限于操作系统,而栈空间一般有系统直接分配

B.频繁的申请空间和释放空间,容易造成内存碎片,甚至内存泄漏,栈区由于是自动管理,不存在此问题

C.堆无法静态分配,只能动态分配

D.栈可以通过函数alloca进行动态分配,不过注意,所分配空间不能通过free或delete进行释放

答案:C 


2.C++内存管理方式

C++为了解决自定义类型的内存管理,提出了自己的内存管理方式:通过newdelete操作符进行动态内存管理。

2.1new/delete操作内置类型

void Test()
{
	// 动态申请一个int类型的空间
	int* ptr4 = new int;
	// 动态申请一个int类型的空间并初始化为10
	int* ptr5 = new int(10);
	// 动态申请10个int类型的空间
	int* ptr6 = new int[3];//int* ptr6 = new int[3]{1,2,3}初始化
	delete ptr4;
	delete ptr5;
	delete[] ptr6;
}

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用
new[]和delete[],注意:匹配起来使用

2.2new/delete操作自定义类型

class A
{
public:
	A(int a = 0)
		: _a(a)
	{
		cout << "A():" << this << endl;
	}
	~A()
	{
		cout << "~A():" << this << endl;
	}
private:
	int _a;
};

int main()
{
	A* p1 = (A*)malloc(sizeof(A));
	A* p2 = new A(1);
	free(p1);
	delete p2;
	// 内置类型是几乎是一样的
	int* p3 = (int*)malloc(sizeof(int)); // C
	int* p4 = new int;
	free(p3);
	delete p4;
	A* p5 = (A*)malloc(sizeof(A) * 10);
	A* p6 = new A[10];
	free(p5);
	delete[] p6;
	return 0;
}

new/delete 和 malloc/free最大区别:

new/delete对于【自定义类型】除了开空间,还会调用构造函数和析构函数.


3.operator new与operator delete函数

operator new与operator delete是系统提供的两个全局函数,本质上可以等价为malloc和free,他们不会调用构造函数与析构函数.


那C++为什么会存在这两个全局函数,他们的意义是什么呢?

我们知道new操作符可以干两件事:

1.开空间

2.调用构造函数


那开空间是怎么开的呢?

实际上就利用了operator new这个全局函数.


可是本来不是有malloc,为啥又单独弄一个operator new呢?

我们知道C++是面向对象的语言,而malloc如果申请失败的话返回的是0,可是面向对象的语言可不认这个0,面向对象语言对于失败的处理一般都是抛异常,也就是说operator new就是malloc的封装,只不过多实现了抛异常这个过程罢了.

那delete在底层释放空间时也是会调用operator delete,其余的细节和上面相似就不过多赘述了.

另外对于new T[n]和delete[],C++也提供了他们对应开空间的全局函数,分别为operator new[]与operator delete[],实际上这两个全局函数的内部还是operator new与operator delete,大家可以理解为换皮(仅为了区分用).

【C++】内存管理(new与delete),C++,c++,开发语言,学习


🐸总结一下🐸


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来释
放空间


4.高频面试题

👓malloc/free和new/delete的区别👓

共同点是:都是从堆上申请空间,并且需要用户手动释放。

不同的地方是:
1. malloc和free是函数new和delete是操作符
2. malloc申请的空间不会初始化new可以初始化
3. malloc申请空间时,需要手动计算空间大小并传递new只需在其后跟上空间的类型即可,如果是多个对象,[]中指定对象个数即可
4. malloc的返回值为void*, 在使用时必须强转new不需要,因为new后跟的是空间的类型
5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空new不需要,但是new需要捕获异常
6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理


=========================================================================

如果你对该系列文章有兴趣的话,欢迎持续关注博主动态,博主会持续输出优质内容

🍎博主很需要大家的支持,你的支持是我创作的不竭动力🍎

🌟~ 点赞收藏+关注 ~🌟

========================================================================= 文章来源地址https://www.toymoban.com/news/detail-754089.html

到了这里,关于【C++】内存管理(new与delete)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++如何进行内存管理 (new、delete)

    我成功是因为我有决心,从不踌躇。——拿破仑  本章是关于c++内存管理的文章,字数不多,内容简单,希望对你有所帮助!! 话不多说安全带系好,发车啦 (建议电脑观看) 。 附:红色,部分为重点部分;蓝颜色为需要记忆的部分(不是死记硬背哈,多敲);黑色加粗或

    2024年02月08日
    浏览(97)
  • C++内存管理(2)new、delete详解

    目录 new operator(new操作) new类对象时加不加括号的差别 new工作任务 delete工作任务 new和delete 堆区空间操作(对比malloc和free) new和delete操作基本类型的空间 new和delete操作基本类型的数组 new和delete操作类的空间 new和delete操作对象数组 new内存分配细节探秘 为什么要尽可能少的

    2024年02月09日
    浏览(47)
  • 【C++破局】C++内存管理之new与deleted剖析

    📚lovewold少个r博客主页     ⚠️ 本文重点 : c++内存管理部分知识点梳理 👉 【C-C++入门系列专栏】 : 博客文章专栏传送门 😄 每日一言 :花有重开日,人无再少年! C/C++的内存分配机制 内存分区 1. 内核空间(Kernel Space): 2. 栈空间(Stack): 3. 内存映射段(Memory Mapp

    2024年02月05日
    浏览(39)
  • 【C++】C/C++内存管理-new、delete

    ヾ(๑╹◡╹)ノ\\\" 人总要为过去的懒惰而付出代价 ヾ(๑╹◡╹)ノ\\\" 代码展示: 栈区 :局部变量 sizeof(数组名):整个数组的大小 sizeof(字符串):注意‘\\0’ 栈又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的。 内存映射段是高效的I/O映射方式,用于装载

    2024年02月11日
    浏览(44)
  • 【C++初阶】七、内存管理(C/C++内存分布、C++内存管理方式、operator new / delete 函数、定位new表达式)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【C++初阶】六、类和对象(初始化列表、static成员、友元、内部类)-CSDN博客  ==================

    2024年02月05日
    浏览(42)
  • 【C++入门】new和delete(C/C++内存管理)

    1.C/C++内存分布 我们先来看一个小问题: 问题: 下面我们就来简单分析一下: 首先 globalVar 是一个全局变量,其次 staticGlobalVar 是一个静态全局变量, staticVar 是静态局部变量,都在静态区(数据段)。最后 localVar 是个局部变量, num1 是个整型数组,那它们是在栈上的。 ch

    2024年02月11日
    浏览(38)
  • 【C++干货基地】深度理解C++中的高效内存管理方式 new & delete

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 : 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活!   哈喽各位铁汁们好啊,我是博主鸽芷咕《C++干货基地》是由我的襄阳家乡零食基地有感而发,不知道各位的城市有没有这种实惠又全面的零食基地呢?C++ 本身作

    2024年04月26日
    浏览(38)
  • 【C++庖丁解牛】C++内存管理 | new和delete的使用以及使用原理

    📙 作者简介 :RO-BERRY 📗 学习方向:致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持 我们先来看下面的一段代码和相关问题 选择题: 选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)

    2024年03月09日
    浏览(54)
  • C/C++内存管理(含C++中new和delete的使用)

    我们先来看下面的一段代码和相关问题。 说明 : 栈 又叫堆栈– 非静态局部变量/函数参数/返回值 等等,栈是向下增长的。 内存映射段 是高效的 I/O 映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。( Linux 课程如果没学到

    2024年02月05日
    浏览(42)
  • 【C++】深入探讨内存管理:malloc/free与new/delete的区别以及如何避免内存泄漏

    在软件开发中,正确处理内存管理是至关重要的一环。在C++编程中,我们经常会用到动态内存管理的工具,比如 malloc/free 和 new/delete 。本文将深入探讨 malloc/free 与 new/delete 之间的区别,以及如何有效地避免内存泄漏问题。 都是用于从堆上申请空间,并需要手动释放。 mallo

    2024年02月22日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包