当前位置: 首页 > news >正文

面试官:小伙子,说说C/C++是如何进行内存管理的?我:……

要努力,但不要着急,繁花锦簇,硕果累累,都需要过程!

 

目录

 前言:

1.C/C++内存分布

 2.C/C++动态内存管理方式

2.1C语言动态内存管理:

2.2C++语言动态内存管理:

2.3operator new和operator delete函数:

2.4new和delete的实现原理:

3.常见的面试题

总结:


 前言:

本篇是主要介绍关于C语言和C++语言如何进行动态内存管理,动态内存管理不仅在语言学习的路上非常重要,而且也是在面试的时候面试官通常会问到的一个热点问题。

1.C/C++内存分布

在编译器上我们写完代码之后,代码会保存到文件中,当我们编译链接完成之后,会生成一个.exe的可执行程序,此时我们的代码会根据不同的类型保存到虚拟进程地址空间,如下图

1.C/C++中程序内存划分

不同区域变量保存类型:

栈:局部变量,函数形参   

堆区:malloc,calloc,realloc申请的空间

静态区:全局变量,static修饰的全局变量,static修饰的局部变量

代码段(常量区):字符常量等  

2.内存区域分布练习:

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);
}

 2.C/C++动态内存管理方式

在C/C++中我们经常会向堆上申请空间,因为堆上的空间比较大,但是堆上申请的空间如果使用者自己不主动释放的时候就会造成内存泄漏,因此既好用又难用,成为面试官针对程序员对语言掌握情况而常问的问题

2.1C语言动态内存管理:

关于对C语言动态内存的介绍,前边已经介绍,详情请戳—>C语言动态内存详解

2.2C++语言动态内存管理:

C++通过两个操作符向堆上申请空间的:

new:向堆上申请空间

delete:释放申请的空间

int main()
{
	//申请内存
	int* p = new int;
	//释放内存
	delete p;
	return 0;
}

注:内置类型申请的内存空间默认不初始化

初始化的方式:

 一次性申请一块大的空间:

C++中的new和delete与C语言的malloc和free在用法上并没有什么区别,对于内置类型效果相同但是对于自定义类型,new和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* p = new A;
	delete p;
	return 0;
}

2.3operator new和operator delete函数:

newdelete是用户进行动态内存申请和释放的操作符,operator newoperator delete
系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间

new和delete底层调用:可以通过反汇编进行观察

 而operator new和operator delete函数又调用的是malloc和free

2.4new和delete的实现原理:

内置类型:

如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:
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来释
放空间

3.常见的面试题

 

1.malloc/free和new/delete的区别?

共同特点:

malloc/free和new/delete都是从堆上申请空间,使用完之后需要手动释放

不同点:

1.malloc和free是函数,new和delete是操作符;

2.对于自定义类型malloc申请的空间不会初始化,new申请的空间会调用构造函数进行初始化

3.malloc申请空间需要传递空间大小,new只需在后面跟上空间大小即可,如果是多个对象,只需在[]中指明对象的个数即可;

4.malloc的返回类型是void*,在使用的时候必须强转,new不需要;

5.malloc空间申请失败时返回NULL, new空间申请失败抛异常;

6.申请自定义类型的对象时malloc和free不会调用构造函数和析构函数对空间进行初始化,和对象资源的清理,new和delete会调用构造函数和析构函数完成对象的初始化和对象资源的清理

2.什么是内存泄漏,内存泄漏的危害是什么?

内存泄漏是指因为错误或疏忽造成程序未能释放已经不再使用内存的情况,内存泄漏并不是指内存在物理上的消失,而是应用程序在分配某块内存后,因为设计错误,失去了对该内存的控制,因而造成了内存的泄漏

内存泄漏的危害:长期运行的程序出现内存泄漏,会造成程序越来越卡,最终会出现卡死的现象

总结:

对内存的申请和使用是在学习的过程中必不可少的,但是在使用的时候,我们应该要学会正确的使用,防止造成内存泄漏等问题

 

相关文章:

  • 哈希表练习题
  • java算法题42501
  • LoRa技术在物联网领域的安全性挑战与应对策略分享
  • 某企业征信Oracle数据库跑批耗时较长问题简述分析报告
  • Golang | Leetcode Golang题解之第48题旋转图像
  • Oracle Linux 8.8 一键安装 Oracle 11GR2 RAC(231017)
  • 坚持刷题|二叉树展开为链表
  • Docker基础(一)
  • React18源码: Fiber树的初次创建过程图文详解
  • 二 线性代数-向量
  • 自动驾驶---行业发展及就业环境杂谈
  • Vue3前端实现一个本地消息队列(MQ), 让消息延迟消费或者做缓存
  • STL容器 —— map和set的模拟实现
  • 软考知识点---06文件管理与作业管理---01文件管理
  • API网关基础认知
  • 腾讯云Ubuntu18.04配置深度学习环境
  • 反常积分敛散性的比较判别法专题(及常用反常积分)
  • pythond大屏可视化
  • 知识图谱-生物信息学-医学论文(Chip-2022)-BCKG-基于临床指南的中国乳腺癌知识图谱的构建与应用
  • 力扣 每日一题 902. 最大为 N 的数字组合【难度:困难,rating: 1989】(数学 / 数位dp)
  • 奇迹mu服务器安全和优化设置
  • OC 基础 导航栏UITabBarController的使用(源码)
  • 人脸识别项目FFmpeg+OpenCV+虹软SDK
  • ITRS 与 GCRS 之间的坐标转换
  • 【图像重建】基于matlab SIDER算法图像压缩重建【含Matlab源码 2170期】
  • 多线程同步-条件变量
  • JS(第八课)循环语句中常用到的案例
  • 2022软考高项十大领域知识整理(四)-人力资源管理、干系人管理、采购管理
  • 深度学习基础之BatchNorm和LayerNorm
  • 【Spring】面向切面编程详解(AOP)
  • 力扣(LeetCode)75. 颜色分类(C语言)
  • LeetCode算法题整理(200题左右)