【C++】动态内存管理 ⑤ ( 基础数据类型数组 内存分析 | 类对象 内存分析 | malloc 分配内存 delete 释放 | new 分配内存 free 释放内存 )

2023-09-21 21:45:00


博客总结 :

  • C 语言中 使用 malloc 分配的内存 , 使用 free 进行释放 ;
  • C++ 语言中 推荐 使用 new 分配的内存 , 使用 delete 进行释放 ;
  • 对于类对象来说 :
    • 使用 new 操作符 , 可以自动调用 类构造函数 进行初始化操作 ;
    • 使用 delete 操作符 , 可以自动调用 类析构函数 进行析构操作 ;
    • 因此这里建议 使用 new 创建类对象 , 使用 delete 释放对象 ;
  • 对于普通类型来说 :
    • new 操作符 与 malloc 函数 作用相同 , 都是在堆内存中为 数据分配内存 ;
    • delete 操作符 与 free 函数 作用相同 , 都是在堆内存中为 数据分配内存 ;




一、基础数据类型数组 内存分析



这里特别注意 , 本章节分析的 基础数据类型 的 数组 的 内存分配与释放 ,

注意与 类对象 数组 的内存动态管理 进行区分 ;


1、malloc 分配内存 delete 释放内存


使用 malloc 函数 , 为 基础数据类型数组 分配内存 , 是可以使用 delete 操作符 释放该内存的 ;


首先 , 使用 malloc 函数 , 为 int 数组分配内存空间 , 数组中存在 2 个 int 类型的元素 ;

int* p = (int*)malloc(sizeof(int) * 2);

然后 , 使用 delete 操作符 , 将 上述分配的 int 数组内存进行释放 ;

delete(p);

上述过程执行正常完成 , 期间没有报错 ;


代码示例 :

#include "iostream"
using namespace std;

int main()
{

	// 使用 malloc 申请数组 内存空间
	int* p = (int*)malloc(sizeof(int) * 2);
	p[0] = 10;
	p[1] = 20;

	cout << "p[0] = " << p[0] << " , p[1] = " << p[1] << endl;

	// malloc 申请的内存 使用 delete 释放
	delete(p);


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
}

执行结果 : 上述代码可以正常执行 , 没有警告与报错 , 说明对于 基础数据类型的数组 来说 , malloc 与 new 的操作是一致的 , 使用 malloc 分配的堆内存 , 使用 delete 也可以释放 ;

p[0] = 10 , p[1] = 20
Press any key to continue . . .

在这里插入图片描述


2、new 分配内存 free 释放内存


使用 new 操作符 , 为 基础数据类型数组 分配内存 , 可以使用 free 函数 释放该内存 ;


首先 , 使用 new 操作符 , 为 int 数组分配内存空间 , 数组中存在 2 个 int 类型的元素 ;

int* p = new int[2];

然后 , 使用 free 函数 , 将 上述分配的 int 数组内存进行释放 ;

free(p);

上述过程执行正常完成 , 期间没有报错 ;


代码示例 :

#include "iostream"
using namespace std;

int main()
{

	// 使用 new 申请数组 内存空间
	int* p = new int[2];
	p[0] = 10;
	p[1] = 20;

	cout << "p[0] = " << p[0] << " , p[1] = " << p[1] << endl;

	// new 申请的内存 使用 free 释放
	free(p);


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
}

执行结果 : 上述代码可以正常执行 , 没有警告与报错 , 说明对于 基础数据类型的数组 来说 , malloc 与 new 的操作是一致的 , 使用 new 分配的堆内存 , 使用 free 也可以释放 ;

在这里插入图片描述





二、类对象 内存分析




1、malloc 分配内存 delete 释放内存


使用 malloc 函数 为 Student 类对象分配 堆内存 , 不会调用 Student 的构造函数 , 只是单纯的在 堆内存中分配了一块内存 ;

Student* p = (Student*)malloc(sizeof(Student));

分配完内存后 , 可以使用 p->m_age 访问 Student 对象的成员 ;

使用 delete 操作符 , 可以释放有 malloc 申请的 类对象内存空间 , 该操作会调用 Student 类的析构函数 ;

delete(p);

代码示例 :

#include "iostream"
using namespace std;

class Student
{
public:
	// 带参构造函数
	Student(int age, int height)
	{
		m_age = age;
		m_height = height;
		cout << "执行 Student 的构造函数" << endl;
	}

	~Student()
	{
		cout << "执行 Student 的析构函数" << endl;
	}

public:
	int m_age;		// 年龄
	int m_height;	// 身高
};

int main()
{

	// 使用 malloc 申请 Student 对象的 内存空间
	// malloc 不会调用 类对象的 构造函数
	Student* p = (Student*)malloc(sizeof(Student));

	cout << "p->m_age = " << p->m_age << " , p->m_height = " << p->m_height << endl;

	// malloc 申请的内存 使用 delete 释放
	delete(p);


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
}

执行结果 :

p->m_age = -842150451 , p->m_height = -842150451
执行 Student 的析构函数
Press any key to continue . . .

在这里插入图片描述


2、new 分配内存 free 释放内存


使用 new 操作符 为 Student 类对象分配 堆内存 , 会调用 Student 的构造函数 , 先在堆内存为 Student 对象分配内存 , 然后再调用构造函数进行初始化 ;

	// 使用 new 操作符 申请 Student 对象的 内存空间
	// new 操作符 会调用 类对象的 构造函数
	Student* p = new Student(10, 150);

分配完内存后 , 可以使用 p->m_age 访问 Student 对象的成员 ;

使用 free 函数 可以释放 由 new 操作符 申请的 类对象内存空间 , 该操作不会调用 Student 类的析构函数 ;

	// new 操作符 申请的内存 使用 free 释放
	free(p);

代码示例 :

#include "iostream"
using namespace std;

class Student
{
public:
	// 带参构造函数
	Student(int age, int height)
	{
		m_age = age;
		m_height = height;
		cout << "执行 Student 的构造函数" << endl;
	}

	~Student()
	{
		cout << "执行 Student 的析构函数" << endl;
	}

public:
	int m_age;		// 年龄
	int m_height;	// 身高
};

int main()
{

	// 使用 new 操作符 申请 Student 对象的 内存空间
	// new 操作符 会调用 类对象的 构造函数
	Student* p = new Student(10, 150);

	cout << "p->m_age = " << p->m_age << " , p->m_height = " << p->m_height << endl;

	// new 操作符 申请的内存 使用 free 释放
	free(p);


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
}

执行结果 : 执行时 , 使用 new 操作符调用了 Student 对象的构造函数 ,

执行 Student 的构造函数
p->m_age = 10 , p->m_height = 150
Press any key to continue . . .

在这里插入图片描述

更多推荐

使用亚马逊云服务器在 G4 实例上运行 Android 应用程序

随着Android应用程序和游戏变得越来越丰富,其中有些甚至比PC上的软件更易于使用和娱乐,因此许多人希望能够在云上运行Android游戏或应用程序,而在EC2实例上运行Android的解决方案可以让开发人员更轻松地测试和运行Android应用程序。在这篇博客文章中,我们将展示如何使用NICEDCV在Anbox中运行A

【JDK 8-Lambda】3.1 Java高级核心玩转 JDK8 Lambda 表达式

一、什么是函数式编程?二、什么是lambda表达式?1.先看两个示例A.【创建线程】B.【数组排序-降序】2.lambda表达式特性A.使用场景(前提):B.语法(params)->expressionC.参数列表D.方法体F.好处一、什么是函数式编程?将一个函数(也称“行为”)作为一个参数进行传递面向对象编程是对数据

【Redis】Redis 的学习教程(十一)之使用 Redis 实现分布式锁

1.分布式锁概念在多线程环境下,为了保证数据的线程安全,锁保证同一时刻,只有一个可以访问和更新共享数据。在单机系统我们可以使用synchronized锁、Lock锁保证线程安全。synchronized锁是Java提供的一种内置锁,在单个JVM进程中提供线程之间的锁定机制,控制多线程并发。只适用于单机环境下的并发控制。

解决Nacos配置刷新导致定时器停止执行的问题

1.问题描述我使用了一个定时器类来执行某个任务,并且使用Nacos作为配置中心来管理定时器的配置。我发现当Nacos配置发生变化时,定时器实例会停止执行任务,导致任务无法按预期执行。2.原先的实现方式以下是我原先的代码实现方式:@Component@RefreshScope@RequiredArgsConstructo

英飞凌TC3xx--深度手撕HSM安全启动(四)--TC3xx HSM使能和配置技巧

上一章,我们简单聊了下英飞凌TC3xx的HSM的系统框架、相关UCB、Host和HSM通信模块。今天着重分析HSM的使能。1.系统引入HSM的思考为什么要增加HSM信息安全方面考虑,系统的安全启动、ECU之间安全数据的交互、ECU内部的敏感信息保存TC3xx使能HSM后,HSM的代码应该存放在哪里?在上一章,我们了解到

C++的移动构造和移动赋值运算符

右值引用右值引用(rvaluereferences)是一种新的用于绑定右值的引用类型。那么什么是右值?右值通常是编译器生成的用于表达式计算的临时变量或常量。目前来说,我们还不能安全地使用引用变量来绑定右值。从编译原理上讲,右值是只存在于表达式计算时的未命名值。下面这一表达式产生了一个右值:x+(y*z);//AC++e

SpringBoot携带Jre绿色部署项目_免安装Jdk[Linux服务器]

文章目录SpringBoot携带Jre绿色部署项目[Linux服务器]1.实现步骤2.自测成功,如下2-1环境准备2-2运行项目SpringBoot携带Jre绿色部署项目[Linux服务器]说明:实际应用的不方便场景:1.实际项目部属时,现有服务器可能已安装有Jdk,和自己项目的Jdk版本不一致,不敢轻易安装自己使用的

解决Permission is not allowed后基于Ubuntu23.04安装配置docker与docker-compose

参考:Docker官网-InstallDockerEngineonUbuntu虚拟机里安装ubuntu-23.04-beta-desktop-amd64,开启SSH(换源、备份),配置中文以及中文输入法等基于CentOS7安装配置docker与docker-compose一、InstallusingtheAptrepo

代码随想录算法训练营第二天(C) | 977.有序数组的平方 209.长度最小的子数组 59.螺旋矩阵

文章目录前言一、977.有序数组的平方二、209.长度最小的子数组三、59.螺旋矩阵总结前言java版:代码随想录算法训练营第二天|977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵_愚者__的博客-CSDN博客一、977.有序数组的平方双指针法:int*sortedSquares(int*nums,in

二进制 Deploy Kubernetes v1.23.17 超级详细部署

文章目录1.预备条件2.基础配置2.1配置root远程登录2.2配置主机名2.3安装ansible2.4配置互信2.5配置hosts文件2.6关闭防firewalld火墙2.7关闭selinux2.8关闭交换分区swap2.9修改内核参数2.10安装iptables2.11开启ipvs2.12配置limits参数2.1

nginx详解

目录1什么是nginx2Nginx功能2.1正向代理2.2反向代理2.3负载均衡2.4动静分离3区别4Docker安装nginx5nginx配置文件介绍1什么是nginxnginx是一个高性能的http和反向代理服务器,特点是占有内存少、并发能力强,事实上nginx的并发能力的确在同类的服务器中表现较好。nginx转为

热文推荐