C/C++内存管理,malloc,realloc,calloc,new,delete详解!!!

1.初步了解内存中各个区间存储的数据特征

1.栈区:存储一些局部变量、函数参数、返回值等,跟函数栈振有关,出了作用域,生命周期结束。

2.堆区:用于动态开辟空间,如果不主动销毁空间,则程序运行结束,生命周期结束。

3.数据段(静态区):static修饰的静态变量和全局变量,程序运行结束,生命周期结束。

4.代码段(常量区):可执行的代码和常量。

练习

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 . 代码段 ( 常量区 )
globalVar 在哪里? __1__   staticGlobalVar 在哪里? __2__
staticVar 在哪里? __3__   localVar 在哪里? __4__
num1 在哪里? __5__
char2 在哪里? __6__   * char2 在哪里? __7_
pChar3 在哪里? __8__       * pChar3 在哪里? __9__
ptr1 在哪里? __10__         * ptr1 在哪里? __11__
1.C       2.C       3.C        4. A       5.A       
6.A        7. A       8.A        9.D        10.A        11.B
结合上图可以得知,cha2其本身存放在栈区,指针指向栈区中数组首元素的地址,再将静态区中"abcd"赋值给数组,所以*char指向的元素在栈区!!!
pChar3其本身存放在栈区,指向静态区中存放"abcd"字符串的首地址!!!

2.c语言实现内存管理

2.1malloc

在堆上开一快符合你预期大小的一块空间,并且返回指向该地址空间的指针

void* malloc (size_t size);

size:开多大的空间,单位是字节

2.2realloc

如果malloc开辟出来的空间开少了,realloc可以在堆上重新开一块符合你预期大小的空间,并返回指向该空间的指针

void* realloc (void * ptr,size_t size);

ptr:初始空间的地址

size:将空间开辟到多大

 2.3calloc

用于对开辟的空间进行初始化,calloc会将开辟的空间中每个元素初始化为0

void* realloc (size_t num,size_t size);

num:分配的元素数量

size:每个元素的大小

3.c++实现内存管理

3.1 new/delete new []/delete []

在c++中,有两对操作符new/delete、new []/delete [],他们的作用是负责开空间和释放空间!!!

new作用跟malloc类似,delete作用跟free类似

new和delete在面对自定义类型时会去调用构造函数和析构函数

new =先申请对象空间 再调用构造函数

delete = 先调用析构函数 再释放对象空间

3.1.1内置类型

当需要开一个整形的空间时。

int main()
{ //mallocint* p1 = (int*)malloc(sizeof(int));//new开空间用法跟malloc不同,但是作用相同,都是负责开空间!!!int* p2 = new int;//freefree(p1);//deletedelete(p2);return 0;
}

当需要开多个空间时 例如开10个int类型的空间 需要加上[]

int main()
{int* p1 = (int*)malloc(sizeof(int)*10);int* p2 = new int[10];free(p1);delete[](p2);return 0;
}
3.1.2自定义类型

new和delete在面对自定义类型时会去调用构造函数和析构函数

new =先开空间 再调用构造函数

delete = 先调用析构函数 再释放空间

class Stack
{
public:Stack(int capacity = 4){_a = new int[capacity];int _top = 0;int _capacity = capacity;}~Stack(){delete (_a);_a = nullptr;_top = 0;_capacity = 0;}
private:int* _a;int _top;int _capacity;
};
int main()
{Stack* p2 = new Stack;//new先开空间 再去调用构造函数delete(p2);//delete先调用析构函数,再去释放空间return 0;
}

如果需要开10个Stack类型的空间 用new[] 和 delete[]

int main()
{Stack* p2 = new Stack[10];//new先开空间 再去调用构造函数delete[](p2);//delete先调用析构函数,再去释放空间return 0;
}

 3.2new/delete底层实现原理

3.2.1 全局函数 operator new/operator delete

要知道原理,我们就得先知道operatot new / operator delete 这两个全局函数

在c++中,有这样两个全局函数,他们的作用跟malloc、free类似,都是负责开空间和释放空间!!!

注意:operator new / operator delete 不是new/delete的重载,而是两个全局函数!!!

我们知道malloc申请空间失败的时候,会返回空。而operator new申请空间失败的时候则会抛异常。我们可以理解为operator是封装的malloc。

也就是说operator new 和mclloc除了申请空间失败的处理方法不同,其他的用法以及功能是相同的!!!

operator delete 可以理解为跟operator new对应,其用法和功能跟free完全一样!!!

int main()
{Stack* p1 = (Stack*)malloc(sizeof(Stack));free(p1);//operator new底层用的是mallocStack* p2 = (Stack*)operator new (sizeof(Stack));//operator delete底层用是freeoperator delete(p2);return 0;
}
3.2.2 new/delete 和 operator new/operator delete的关系

new = 1.申请对象空间 + 2.调用构造

delete = 1.调用析构 + 2.释放对象空间

在底层原理上,new的第一步申请对象空间底层就是调用operator new函数,

operator的第二步释放对象空间底层就是调用operator operator函数.

也就是说下面两段不同的代码,起到的作用都是相同的 

int main()
{Stack* p1 = new Stack;delete (p1);//等价于newStack* p2 = (Stack*)operator new (sizeof(Stack));//定位new显示调用构造函数new(p2)Stack;//等价于deletep2->~Stack();operator delete(p2);return 0;
}

我们到汇编语言的角度证明一下

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

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

相关文章

因式分解的几何意义

本来准备和女儿一起玩一道几何题,想想还是算了,不如讲点更有趣的。 任何因式分解都是在堆积木,不信你看: 二项式定理,洋灰三角,都是面积,体积,超维体积的拼接,一个大超…

Python 安装django-cors-headers解决跨域问题

一、PythonCorsHeaders概念 PythonCorsHeaders是一个轻量级的Python工具,用于解决跨域HTTP请求的问题。它允许你指定哪些网站或IP地址可以访问你的站点,并控制这些站点可以访问哪些内容。 现代网站越来越多地使用Ajax技术,使得浏览器能够从不…

【人工智能】Chatgpt的训练原理

前言 前不久,在学习C语言的我写了一段三子棋的代码,但是与我对抗的电脑是没有任何思考的,你看了这段代码就理解为什么了: void computerMove(char Board[ROW][COL], int row, int col) {while (1){unsigned int i rand() % ROW, …

设计模式之十二:复合模式

模式通常被一起使用,并被组合在同一个解决方案中。 复合模式在一个解决方案中结合两个或多个模式,以解决一般或重复发生的问题。 首先重新构建鸭子模拟器: package headfirst.designpatterns.combining.ducks;public interface Quackable …

【网络】传输层 --- 详解TCP协议

目录 一、协议段格式及其策略确认应答(ACK)机制6个标志位超时重传流量控制滑动窗口1、先谈滑动窗口一般情况2、再谈特殊窗口 拥塞控制拥塞窗口 延迟应答&&捎带应答面向字节流粘包问题 二、三次握手和四次挥手三次握手为什么是3次?不是2、4、5、6次呢 四次挥…

NoSQL基础知识小结

NoSQL 基础知识 什么是 NoSQL? NoSQL(Not Only SQL 的缩写)泛指非关系型的数据库,主要针对的是键值、文档以及图形类型数据存储。 NoSQL 数据库天生支持分布式,数据冗余和数据分片等特性,旨在提供可扩展的高可用高…

【代码】基于VMD(变分模态分解)-SSA(麻雀搜索算法优化)-LSTM的光伏功率预测模型(完美复现)matlab代码

程序名称:基于VMD(变分模态分解)-SSA(麻雀搜索算法优化)-LSTM的光伏功率预测模型 实现平台:matlab 代码简介:提出了变分模态分解(VMD)和麻雀搜索算法(SSA)与长短期记忆神经网络 (LSTM)相耦合,…

Spark-06:Spark 共享变量

目录 1.广播变量(broadcast variables) 2.累加器(accumulators) 在分布式计算中,当在集群的多个节点上并行运行函数时,默认情况下,每个任务都会获得函数中使用到的变量的一个副本。如果变量很…

Android 相机库CameraView源码解析 (一) : 预览

1. 前言 这段时间,在使用 natario1/CameraView 来实现带滤镜的预览、拍照、录像功能。 由于CameraView封装的比较到位,在项目前期,的确为我们节省了不少时间。 但随着项目持续深入,对于CameraView的使用进入深水区,逐…

【LeetCode】挑战100天 Day17(热题+面试经典150题)

【LeetCode】挑战100天 Day17(热题面试经典150题) 一、LeetCode介绍二、LeetCode 热题 HOT 100-192.1 题目2.2 题解 三、面试经典 150 题-193.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站,提供各种算法和数据结构的题目&…

[建议收藏] 一个网站集合所有最新最全的AI工具

今天给大家推荐一个宝藏的AI工具合集网站,有了这个网站,你们再也不用去其他地方找AI工具了。 名称:AI-BOT工具集 这个网站精选1000AI工具,并持续每天更新添加,包括AI写作、AI绘画、AI音视频处理、AI平面设计、AI自动编…

Atcoder Beginner Contest 330——A~F题

A - Counting Passes Description Problem Statement N N N people labeled 1 , 2 , … , N 1,2,\dots,N 1,2,…,N took an exam, and person i i i scored A i A_i Ai​ points. Only those who scored at least L L L points pass this exam. Determine how many peopl…

SpringBoot:邮件发送

官网文档:39. Sending Email (spring.io)。 Sending Email Spring框架提供了JavaMailSender实例,用于发送邮件。 如果SpringBoot项目中包含了相关的启动器,那么就会自动装配一个Bean实例到项目中。 在SpringBoot项目中引入如下Email启动器&a…

【数据分享】2019-2023年我国区县逐月新房房价数据(Excel/Shp格式)

房价是一个城市发展程度的重要体现,一个城市的房价越高通常代表这个城市越发达,对于人口的吸引力越大!因此,房价数据是我们在各项城市研究中都非常常用的数据!之前我们分享过2019-2023年我国地级市逐月房价数据&#x…

Spring Boot 项目中读取 YAML 文件中的数组、集合和 HashMap

在 Spring Boot 项目中,我们经常使用 YAML 文件来配置应用程序的属性。在这篇博客中,我将模拟如何在 Java 的 Spring Boot 项目中读取 YAML 文件中的数组、集合和 HashMap。 1. 介绍 YAML(YAML Aint Markup Language)是一种人类…

【Spring集成MyBatis】MyBatis注解开发

文章目录 1. MyBatis的常用注解2. 基于注解的MyBatis增删改查增删改查完整代码加载映射关系测试代码 3. MyBatis的注解实现复杂映射开发一对一操作的实现一对一操作实现的第二种方式一对多操作的实现多对多操作实现 1. MyBatis的常用注解 2. 基于注解的MyBatis增删改查 使用注…

Linux加强篇004-Vim编辑器与Shell命令脚本

目录 前言 1. Vim文本编辑器 1.1 编写简单文档 1.2 配置主机名称 1.3 配置网卡信息 1.4 配置软件仓库 2. 编写Shell脚本 2.1 编写简单的脚本 2.2 接收用户的参数 2.3 判断用户的参数 3. 流程控制语句 3.1 if条件测试语句 3.2 for条件循环语句 3.3 while条件循环语…

【开源】基于JAVA的高校学院网站

项目编号: S 020 ,文末获取源码。 \color{red}{项目编号:S020,文末获取源码。} 项目编号:S020,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学院院系模块2.2 竞赛报名模块2.3 教…

Postman如何使用(三):使用数据文件

数据文件是非常强大的方式使用不同的测试数据来测试我们的API,以检查它们是否在各种情况下都能正常运行。我们可以认为数据文件是“Collection Runner”中每个请求的参数。下面,我们通过一个例子来说明如何使用数据文件。 这篇文章需要结合下面两个文件进…

史上最全前端知识点+高频面试题合集,十二大专题,命中率高达95%

前言: 下面分享一些关于阿里,美团,深信服等公司的面经,供大家参考一下。大家也可以去收集一些其他的面试题,可以通过面试题来看看自己有哪里不足。也可以了解自己想去的公司会问什么问题,进行有针对的复习。…