C++内存管理——new/delete、operator new/operator delete

内存管理

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在哪里?C   staticGlobalVar在哪里?C
      staticVar在哪里?C   localVar在哪里?A
      num1 在哪里?A
     
      char2在哪里?A   *char2在哪里?A
      pChar3在哪里?A      *pChar3在哪里?D
      ptr1在哪里?A        *ptr1在哪里?B
  2. 填空题:

    sizeof(num1) = 40 ;sizeof(char2) = 5 ;      strlen(char2) = 4 ;
      sizeof(pChar3) = 4 ;     strlen(pChar3) = 4 ;
      sizeof(ptr1) = 4 ;

  3. sizeof 和 strlen 区别?
  • sizeof 用于获取变量或数据类型的大小,是一个编译时的操作。
  • strlen 用于获取字符串的长度,是一个运行时的操作,需要遍历整个字符串。

关于内存分配区域详细说明看此文:

动态内存分配之 malloc、calloc、realloc 和 free以及常见动态分配内存错误(附内存分配区域说明)icon-default.png?t=N7T8https://blog.csdn.net/m0_63596031/article/details/135755761?spm=1001.2014.3001.5501

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

void Test ()
{int* p1 = (int*) malloc(sizeof(int));free(p1);int* p2 = (int*)calloc(4, sizeof (int));int* p3 = (int*)realloc(p2, sizeof(int)*10);// 这里需要free(p2)吗?free(p3 );
}

【面试题】

  1. malloc/calloc/realloc的区别?
  2. malloc的实现原理?glibc中malloc实现原理

2. C++内存管理方式

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

(1)new/delete操作内置类型

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

注意:

申请和释放单个元素的空间,使用new和delete操作符

申请和释放连续的空间,使用new[]delete[],注意匹配起来使用。

(2)new和delete操作自定义类型

struct ListNode
{ListNode* _next;int _val;ListNode(int val):_next(nullptr), _val(val){}
};int main()
{// 1.用法上变简洁了,内置类型是几乎是一样的int* p0 = (int*)malloc(sizeof(int)); // Cint* p1 = new int;int* p2 = new int[10]; // new10个int对象delete p1;delete[] p2;// 2.可以控制初始化int* p3 = new int(10); // new一个int对象并初始化成10/*int* p4 = new int[10]{ 1,2,3,4,5 };int* p4 = new int[10]{ 1, 2, 3, 4, 5 };*//*int* p4 = new int[10]{ 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 };*/int* p4 = new int[10]{ 1, 2, 3, 4, 5 };cout << *p4 << endl;delete p3;delete[] p4;// 3.自定义类型,开空间+构造函数// new失败了以后抛异常,不需要检查ListNode* node1 = new ListNode(1);ListNode* node2 = new ListNode(2);ListNode* node3 = new ListNode(3);free(p0);delete node1;delete node2;delete node3;return 0;
}

new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数 ,在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与 free不会。

(3)operator new与operator delete函数

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

operator new 实际也是通过malloc来申请空间,如果 malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施 就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的

(4)new和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来释放空间

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

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

  • 使用格式:

        new (place_address) type或者new (place_address) type(initializer-list)

        place_address必须是一个指针,initializer-list是类型的初始化列表

  • 使用场景:

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++ lambda表达式的使用方法

c lambda表达式的使用方法 C11引入了lambda表达式&#xff0c;它是一种轻量级的匿名函数&#xff0c;允许我们在需要函数的地方直接定义函数&#xff0c;而无需专门声明函数。lambda表达式的语法简洁&#xff0c;并且非常灵活&#xff0c;可以捕获外部变量&#xff0c;具有与普…

Mapper 编写的常用方式

第一种&#xff1a;接口实现类继承 SqlSessionDaoSupport&#xff1a; 使用此种方法需要编写mapper 接口&#xff0c;mapper 接口实现类、mapper.xml 文件。 1&#xff1a; 在 sqlMapConfig.xml 中配置 mapper.xml 的位置 <mappers><mapper resource"mapper.x…

技术速递|.NET 智能组件简介 – AI 驱动的 UI 控件

作者&#xff1a;Daniel Roth 排版&#xff1a;Alan Wang AI 的最新进展有望彻底改变我们与软件交互和使用软件的方式。然而&#xff0c;将 AI 功能集成到现有软件中可能面临一些挑战。因此&#xff0c;我们开发了新的 .NET 智能组件&#xff0c;这是一组真正有用的 AI 支持的 …

OCP-数据库中的小米SU7

oracle ocp ​数据库中的SU7 ​好看又好用 需要找工作和落户的快来

帮助中心最核心的内容,你都知道吗?

帮助中心&#xff0c;其实就是个解决问题的“百事通”。当你在使用某产品时&#xff0c;遇到了一些问题&#xff0c;就可以到帮助中心去查询相关的信息以解决问题。很多公司都会搭建帮助中心&#xff0c;那么&#xff0c;帮助中心的核心内容都有哪些呢&#xff1f;这就是今天我…

Chrome 中安装 Vue 插件 vue-devtools 的简易教程

Vue.js 是一种流行的 JavaScript 框架&#xff0c;用于构建交互式的用户界面。它提供了丰富的开发工具和插件&#xff0c;其中一个非常有用的插件就是 vue-devtools。vue-devtools 可以让开发者在 Chrome 浏览器中轻松调试和检查 Vue 组件的状态、事件和数据流。本篇教程将向你…

损失函数:Cross Entropy Loss (交叉熵损失函数)

损失函数&#xff1a;Cross Entropy Loss &#xff08;交叉熵损失函数&#xff09; 前言相关介绍Softmax函数代码实例 Cross Entropy Loss &#xff08;交叉熵损失函数&#xff09;Cross Entropy Loss与BCE loss区别代码实例 前言 由于本人水平有限&#xff0c;难免出现错漏&am…

【yolo数据集合并方法】

yolo数据集合并方法 1.数据集容2.数据集合并 1.数据集容 包含训练集、验证集和测试集。 每一个数据集中包含图像文件夹和标签文件夹。 yaml文件中定义了配置参数&#xff0c;包括目标识别的class类别&#xff1a; 2.数据集合并 需要修改labels文件夹下txt文件class信息&…

记录shell编程中$1,$@等符号的含义

笔者最近老是遇到shell中的$相关的题目&#xff0c;于是打算写篇文章记录一下。考虑到并没有特别多需要解释的内容&#xff0c;所以并不会进行介绍&#xff0c;上图上表上代码&#xff0c;让机器说话&#xff0c;machine always right test.sh #/bin/bash echo $# $# echo …

gcc原理和使用

gcc gcc是什么 GCC&#xff0c;全称 GNU Compiler Collection&#xff08;GNU 编译器套件&#xff09;&#xff0c;是一套功能强大的编程语言编译器&#xff0c;由自由软件基金会&#xff08;Free Software Foundation, FSF&#xff09;作为GNU项目的一部分开发和维护。它最初…

宝塔使用笔记

1.配置ssl 验证方式&#xff1a;文件验证和dns验证都试一下 参考&#xff1a; https://app.applebyme.cn/cloud/https/23050.html

自定义类型: 联合体和枚举

本文索引 1. 联合体1.1 联合体类型的声明1.2 联合体的特点1.3 相同成员的结构体和联合体对比1.4 联合体大小的计算 2. 枚举类型2.1 枚举类型的声明2.2 枚举类型的优点2.3 枚举类型的使用 前言 : 书接上文, 下面我将继续详解C语言的剩下两个自定义类型: 联合体和枚举 个人主页…

【Linux】tcpdump P2 - 捕获和查看网络数据包

文章目录 7. 选项 -r8. 主机选项9. 逻辑运算符10. 关键字 net11. 关键字 ether12. 关键字 ip6总结 本文主要介绍了如何使用tcpdump来捕获和查看网络数据包。 7. 选项 -r 如果你已经走到了这一步并且写入了一个.pcap文件&#xff0c;你知道你不能使用简单的文本编辑器来读取文…

Linux命令学习—DNS 服务器

1.1、DNS 服务器介绍 DNS domain name system 域名系统 1、网络中&#xff0c;计算机通过 IP 地址来通信 IP 地址记忆困难&#xff0c;为计算机起个好名字 域名概念的提出 DNS 服务&#xff1a;为主机建立 IP 地址与域名之间的映射关系&#xff0c;使用域名来唯一标识网络…

当面试问你接口测试时,不要再说不会了!

很多人会谈论接口测试。到底什么是接口测试&#xff1f;如何进行接口测试&#xff1f;这篇文章会帮到你。 01 前端和后端 在谈论接口测试之前&#xff0c;让我们先明确前端和后端这两个概念。 前端是我们在网页或移动应用程序中看到的页面&#xff0c;它由 HTML 和 CSS 编写…

第十五届蓝桥杯复盘python大学A组——试题B 召唤数学精灵

按照正常思路解决&#xff0c;由于累乘消耗大量时间&#xff0c;因此这不是一个明智的解决方案。 这段代码执行速度非常慢的原因在于它试图计算非常大的数的阶乘&#xff08;累乘&#xff09;&#xff0c;并且对于每一个i的值都执行这个计算。阶乘的增长是极其迅速的&#xff…

SQL数据库管理开发工具:DataGrip 2024(win/mac)激活版

JetBrains DataGrip是一款专业的SQL数据库管理开发工具。DataGrip允许您以不同的方式发展模式以及执行信息查询&#xff0c;并提供服务本地文化历史问题记录&#xff0c;可以提高跟踪您的所有学生活动并保护如果您不选择丢失您的工作。DataGrip允许您通过建立相应的操作按名称就…

HackMyVM-Connection

目录 信息收集 arp nmap WEB web信息收集 dirsearch smbclient put shell 提权 系统信息收集 suid gdb提权 信息收集 arp ┌─[rootparrot]─[~/HackMyVM] └──╼ #arp-scan -l Interface: enp0s3, type: EN10MB, MAC: 08:00:27:16:3d:f8, IPv4: 192.168.9.115 S…

[Linux]--关于进程控制

进程创建,fork/vfork 在linux中fork函数是非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程。 #include <unistd.h> pid_t fork(void); 返回值&#xff1a;自进程中返回0&#xff0c;父进程返回子进程id&#x…