首页 > 系统相关 >C/C++ 内存管理

C/C++ 内存管理

时间:2024-07-22 23:54:14浏览次数:20  
标签:malloc 函数 管理 C++ 内存 operator new delete

C/C++ 内存管理

1. C/C++内存分布

我们先来看下面的一段代码和相关问题
在这里插入图片描述

  1. char2 只是一个字符数组,因此存放在栈上。
  2. 星char2 在 栈上,因为数组名sizeof的时候代表整个数组,但是进行运算的时候,比如说解引用 它是代表首元素的地址。
    图示:
    在这里插入图片描述
    3.PChar3在栈上,首先const限制*PChar3,不能通过PChar3来修改PChar3指向的空间内容,但是指针变量PChar3可以改变,因此PChar3不可能在常量区。
  3. *PChar3 在常量区,原因如下:
    在这里插入图片描述
    4.指针变量ptr1在栈上,指向的内容在堆上,因此 * ptr 在堆上。
    在这里插入图片描述
    【说明】
  4. 又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的。
  5. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。(Linux课程如果没学到这块,现在只需要了解一下)
  6. 用于程序运行时动态内存分配,堆是可以上增长的。
  7. 数据段–存储全局数据和静态数据。
  8. 代码段–可执行的代码/只读常量。

2. C语言中动态内存管理方式:malloc/calloc/realloc/free

在这里插入图片描述
【面试题】

  1. malloc/calloc/realloc的区别?
    malloc 函数用于分配指定大小的内存块,它从堆(heap)中分配内存,但不初始化这些内存。calloc 会将分配的内存初始化为零。realloc 函数用于扩容。
  2. malloc的实现原理? glibc中malloc实现原理

3. C++内存管理方式

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

3.1 new/delete操作内置类型

在这里插入图片描述
在这里插入图片描述
注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[],注意:匹配起来使用。
例子:
在这里插入图片描述
new默认不初始化,但是它也可以初始化,如下:
在这里插入图片描述
注意 :对于内置类型开空间使用malloc或者new几乎是一样的

int* p3 = (int*)malloc(sizeof(int)); // C
int* p4 = new int;

3.2 new和delete操作自定义类型

在这里插入图片描述
注意:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。

4. operator new与operator delete函数(重要点进行讲解)

4.1 operator new与operator delete函数(重点)

new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
在这里插入图片描述
上面会有同学有疑问为什么要operator new,operator delete呢?直接调malloc不香吗?为啥要搞这个东西?有个原因在。首先malloc 失败的结果是什么?是返回空。所有以前用malloc的时候都会检查是否为空。new 呢? C++引出了一个叫异常的东西。通过上述两个全局函数的实现知道,operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。
下面给你们看个new好用的代码:

在这里插入图片描述
为什么不是malloc+构造函数,而是operator new+函数构造,如果operator new 开空间失败了,malloc是返回0。operator new是封装(实际就是封装malloc),所以new失败抛异常实际上是在operator new开空间时(malloc+失败抛异常),从表层角度看malloc是一个函数的用法,new是一个操作符的用法。从底层角度看,new就是malloc,但是它在malloc的基础上加了很多东西,new其实比malloc多做了很多事情,多做了构造函数,失败了要抛异常。
还有个问题就是 new ,delete ,malloc ,free能不能混着使用,我这里建议大家配对使用。因为有时候能对,有时候可能程序会崩溃。混合使用可能导致释放位置不对。
在这里插入图片描述

5. new和delete的实现原理

5.1 内置类型

在这里插入图片描述

5.2 自定义类型

在这里插入图片描述
代码:
在这里插入图片描述

new底层原理图示:
在这里插入图片描述
delete底层原理图示:
在这里插入图片描述
析构 和 operator delete 释放的是不是同一个东西? 答案是:不是,operator delete delete的是谁?是p2指向的这块空间析构,析构是这个A对象上的资源的清理(当然是A对象有资源才需要清理,没有资源要清理,调用析构函数,就直接执行函数体的代码,比如说就只打印了一句)。
在这里插入图片描述

6. 定位new表达式(placement-new) (了解)

定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
使用格式:

new (place_address) type或者new (place_address) type(initializer-list)
place_address必须是一个指针,initializer-list是类型的初始化列表

使用场景:
定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化。

在这里插入图片描述

7. 常见面试题

7.1 malloc/free和new/delete的区别

在这里插入图片描述

7.2 内存泄漏

7.2.1 什么是内存泄漏,内存泄漏的危害

在这里插入图片描述
在这里插入图片描述

7.2.2 内存泄漏分类(了解)

在这里插入图片描述

7.2.3 如何检测内存泄漏(了解)

在vs下,可以使用windows操作系统提供的_CrtDumpMemoryLeaks() 函数进行简单检测,该函数只报出了大概泄漏了多少个字节,没有其他更准确的位置信息。
在这里插入图片描述

标签:malloc,函数,管理,C++,内存,operator,new,delete
From: https://blog.csdn.net/m0_64364831/article/details/140593288

相关文章

  • 05内存情况
    documentReader类型DefaultBeanDefinitionDocumentReaderdelegate类型BeanDefinitionParserDelegate,临时对象属性|-Set<String>usedNames|-ParseStateparseState|-beanNameGenerator(DefaultBeanNameGenerator)BeanDefinition类型GenericBeanDefinition......
  • 【系统规划与管理师】【论文】【资料】IT服务监督管理
    (整理该篇资料作为写作素材)内容涵盖:1、本阶段作为系统规划与管理师应做什么;(what)2、做法的目的和效益;(why)3、本阶段作为系统规划与管理师应怎么做;(how)————应思考的问题:————如何将这些做法及效益串联起来,转换为自己的做法在论文中进行巧妙衔接和说明?(建议可以先采......
  • C++狼人杀游戏
    #include<bits/stdc++.h>#include<cstdio>#include<cstdlib>#include<ctime>#include<windows.h>usingnamespacestd;structIDname{intgeshu;stringNAME;};IDnamejue_se[100];structID{intnum;boollife;......
  • learncpp-1 C++基础
    1C++基础1.1语句和程序结构语句是一条让计算机执行某个动作的指令,是C++语言中最小的独立计算单元在高级语言(例如C++)中,一条语句可能编译成多条机器指令大多数语句以;结尾声明语句跳转表达式语句复合语句选择语句(条件语句)迭代语句(循环语句)try代码块函......
  • python+flask计算机毕业设计快递驿站管理系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着电子商务的迅猛发展,快递行业迎来了前所未有的繁荣期,快递包裹量急剧增长,对快递末端配送服务提出了更高的要求。传统的快递配送模式面临......
  • C++学习笔记
    -------------------------------------------------------------------给一个无单向不循环链表的首结点l,编写程序反转链表,并返回反转后的链表首结点structllist_node{intval;structllist_node*next;};structllist_node*func(structllist_node*l){......
  • c++(4) sophus可视化和计算误差
             CMakeLists.txtproject(test)find_package(PangolinREQUIRED)include_directories(${Pangolin_INCLUDE_DIRS})find_package(fmtREQUIRED)set(FMT_LIBRARIESfmt::fmt)#set(v1_node_filemain.cpp)add_executable(v1_nodemain.cpp)......
  • Visual Studio 2019使用SVN管理源代码
    原文链接:https://blog.csdn.net/g313105910/article/details/119964508第一章、下载安装VisualSVNforVisualStudio2019https://www.visualsvn.com/CSDN下载地址https://download.csdn.net/download/g313105910/21698281安装 完成 VisualStudio2019中已经包含了A......
  • Graylog 是一个开源的日志管理和分析平台
    Graylog是一个开源的日志管理和分析平台,用于集中化日志数据的收集、存储、搜索和可视化。它特别适用于大规模的日志数据管理,并且提供了强大的功能来帮助监控和分析系统日志、应用程序日志和其他类型的事件数据。主要特点集中化日志管理:Graylog能够从多个来源收集日志数据,......
  • 【c++经典面试题】有关string类的深浅拷贝
    题目背景基于自实现string类substr成员函数时遇到的问题。代码展示stringstring::substr(size_tpos,size_tlen)//声明时len的参省值位npos { assert(pos<_size); if(len>_size-pos)//如果len的长度大于有效字符长度,那么重置为有效字符长度 { le......