13.C++内存管理2(C++ new和delete的使用和原理详解,内存泄漏问题)

⭐本篇重点:new, delete的使用和原理

⭐本篇代码:c++学习/04.c++-动态内存管理 · 橘子真甜/c++-learning-of-yzc - 码云 - 开源中国 (gitee.com)

目录

一. new和delete的使用

1.1 操作内置类型

1.2 操作自定义类型

二. new, delete与malloc, free的区别

2.1 相同点

2.2 不同点

三. new/delete原理(operator new 和 operator delete)

3.1 函数operator new / operator delete

3.2 new 和 delete 原理

四. 内存泄漏问题

4.1 什么是内存泄漏?内存泄漏的危害是什么?

4.2 内存泄漏的原因

4.3 避免内存泄漏

五. 下篇文章:STL简介


一. new和delete的使用

        new和delete是C++提供的一对操作符,可以完成对内存的管理。常用于完成内置类型和自定义类型的初始化

        其中,new用于开辟空间,delete使用释放空间

1.1 操作内置类型

#include <iostream>
using namespace std;

int main()
{
	//1.new申请一个int型的变量,并将其赋值为999
	int* a = new int(999);
	
	//2.new申请10个int型的变量
	int* nums = new int[10];
	for (int i = 0; i < 10; i++)
	{
		nums[i] = i;
	}

	cout << *a << endl;

	for (int i = 0; i < 10; i++)
	{
		cout << nums[i] << " ";
	}

	//释放申请的空间
	delete a;
	delete[] nums;
	return 0;
}

分析:我们申请了并初始化一个变量a,以及一个数组nums。然后输出它们的值。运行结果如下:

要注意new和delete的搭配使用

new和delete用于开辟和释放一个元素。

new 类型[]  和 delete[] 用于开辟和释放连续的空间。

1.2 操作自定义类型

new和delete还能够操作自定义类型。

new初始化自定义类型的时候会调用其 构造函数

delete释放自定义类型的时候会调用其 析构函数

#include <iostream>
using namespace std;

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "调用A的构造函数" << endl;
	}

	~A()
	{
		cout << "调用A的析构函数" << endl;
	}

	void print()
	{
		cout << _a << endl;
	}
private:
	int _a;
};
int main()
{
	A* p1 = new A;
	p1->print();

	A* p2 = new A(1);
	p2->print();

	A* p3 = new A[5]; //初始化连续的变量

	delete p1;
	delete p2;
	delete[] p3;
	return 0;
}

运行结果如下:

二. new, delete与malloc, free的区别

2.1 相同点

new/delete 与 malloc/free 都是在堆上开辟空间,并且需要用户手动释放空间

2.2 不同点

new/delete是C++提供的操作符,malloc/free是C语言提供的库函数

new/delete申请空间会对其进行初始化,malloc/free不会进行初始化

new/delete申请空间会调用其构造函数,释放空间会调用析构函数,malloc/free 申请释放空间不会调用构造函数和析构函数

举例:

#include <iostream>
using namespace std;

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "调用A的构造函数" << endl;
	}

	~A()
	{
		cout << "调用A的析构函数" << endl;
	}

	void print()
	{
		cout << _a << endl;
	}
private:
	int _a;
};

int main()
{
	//new/delete申请空间会初始化
	cout << "new/delete" << endl;
	A* p1 = new A;
	delete p1;

	//malloc/free申请空间不会初始化
	cout << "malloc/free" << endl;
	A* p2 = (A*)malloc(sizeof(A));
	if (NULL == p2)
	{
		cout << "malloc error!" << endl;
		exit(1);
	}
	free(p2);
	p2 = NULL;

	return 0;
}

        malloc申请空间的时候,我们需要将返回的 void* 强制转化为我们需要的类型,并且需要计算我们需要申请的空间,还需要处理返回值为NULL的情况。

        new申请空间不需要强转,不许计算大小直接在后面放我们需要申请的空间类型即可,申请多个变量带上[]即可!不过使用new的时候需要捕获异常

三. new/delete原理(operator new 和 operator delete)

3.1 函数operator new / operator delete

        new/delete是用于动态申请和释放空间的操作符,而operator new 和 operator delete是系统提供的全局函数      

          new在底层调用operator new全局函数来申请空间,delete在底层通过 operator delete全局函数来释放空间。

 operator new 和 operator delete的部分源码如下

//operator new: 该函数通过malloc申请空间
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
// try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
     if (_callnewh(size) == 0)
     {
         // report no memory
         // 如果申请内存失败了,这里会抛出bad_alloc 类型异常
         static const std::bad_alloc nomem;
         _RAISE(nomem);
     }
return (p);
}


//operator delete: 该函数最终是通过free来释放空间的
void operator delete(void *pUserData)
{
     _CrtMemBlockHeader * pHead;
     RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
     if (pUserData == NULL)
         return;
     _mlock(_HEAP_LOCK);  /* block other threads */
     __TRY
         /* get a pointer to memory block header */
         pHead = pHdr(pUserData);
          /* verify block type */
         _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
         _free_dbg( pUserData, pHead->nBlockUse );
     __FINALLY
         _munlock(_HEAP_LOCK);  /* release other threads */
     __END_TRY_FINALLY
     return;
}

//free的实现
#define   free(p)               _free_dbg(p, _NORMAL_BLOCK)

所以我们知道:operator new这个函数 是通过malloc来申请空间的。申请失败的时候会抛出异常,operator delete是通过free来实现释放空间的

3.2 new 和 delete 原理

对于内置类型,new/delete和malloc/free相似。区别见本篇2.2

对于自定义类型:

new原理:

        调用函数 operator new 申请空间,然后在申请的空间上调用构造函数完成对象的构造和初始化

delete原理:

        先在申请的空间上调用对象的析构函数进行清理,然后调用函数 operator free 进行释放对象的空间

四. 内存泄漏问题

4.1 什么是内存泄漏?内存泄漏的危害是什么?

        内存泄漏是因为程序员的疏忽和错误,没有去释放不再使用的内存空间。内存泄漏不是物理内存的消失,而是应用程序分配某段内存后,因为错误设计,导致程序失去了对这段内存的控制,造成空间浪费

        内存泄漏的危害:长期运行的程序出现内存泄漏会导致系统越来越卡,直到卡死。

4.2 内存泄漏的原因

        内存泄漏一般分为堆内存泄漏和系统资源泄漏。

堆:当我们使用malloc/new申请空间之后,使用完了却没有使用delete/new去释放这段空间。结果就是这段空间无法使用

系统资源泄露:指程序使用系统分配的资源,比方套接字、文件描述符、管道等没有使用对应的函数释放 掉,导致系统资源的浪费,严重可导致系统效能减少,系统执行不稳定。

4.3 避免内存泄漏

1 要有良好的工程设计和编码规范,申请完空间之后需要匹配释放空间。

2 有时候我们写了释放空间的代码,由于发生了异常导致这段代码没有被执行。这种时候就需要采用RAII思想和智能指针来解决

3 使用内存泄漏检测工具进行检测

五. 下篇文章:STL简介

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用源码编译虚幻引擎,并打包到安卓平台

用源码编译虚幻引擎&#xff0c;并打包到安卓平台 前往我的博客,获取更优的阅读体验 作业内容: 源码编译UE5.4构建C项目&#xff0c;简单设置打包到安卓平台 编译虚幻 5 前置内容 这里需要将 Epic 账号和 Github 账号绑定&#xff0c;然后加入 Epic 邀请的组织&#xff0c…

golang通用后台管理系统09(系统操作日志记录)

1.日志工具类 package log/**** 日志记录 wangwei 2024-11-18 15:30*/ import ("log""os""path/filepath""time" )// 获取以当前日期命名的日志文件路径 func getLogFilePath() string {currentDate : time.Now().Format("2006-…

基于yolov8、yolov5的电塔缺陷检测识别系统(含UI界面、训练好的模型、Python代码、数据集)

摘要&#xff1a;电塔缺陷检测在电力设备巡检、运行维护和故障预防中起着至关重要的作用&#xff0c;不仅能帮助相关部门实时监测电塔运行状态&#xff0c;还为智能化检测系统提供了可靠的数据支撑。本文介绍了一款基于YOLOv8、YOLOv5等深度学习框架的电塔缺陷检测模型&#xf…

论文阅读 SeedEdit: Align Image Re-Generation to Image Editing

目录 摘要 1 INTRODUCTION 2 SEEDEDIT 2.1 T2I MODEL FOR EDITING DATA GENERATION 2.2 CAUSAL DIFFUSION MODEL WITH IMAGE INPUT 2.3 ITERATIVE ALIGNMENT 3 EXPERIMENTS 3.1 BENCHMARK AND METRICS 3.2 IMAGE EDITING COMPARISON 4 CONCLUSION 摘要 SeedEdit&…

昇思MindSpore第四课---GPT实现情感分类

1. GPT的概念 GPT 系列是 OpenAI 的一系列预训练模型&#xff0c;GPT 的全称是 Generative Pre-Trained Transformer&#xff0c;顾名思义&#xff0c;GPT 的目标是通过Transformer&#xff0c;使用预训练技术得到通用的语言模型。和BERT类似&#xff0c;GPT-1同样采取pre-trai…

Nacos实现IP动态黑白名单过滤

一些恶意用户&#xff08;可能是黑客、爬虫、DDoS 攻击者&#xff09;可能频繁请求服务器资源&#xff0c;导致资源占用过高。因此我们需要一定的手段实时阻止可疑或恶意的用户&#xff0c;减少攻击风险。 本次练习使用到的是Nacos配合布隆过滤器实现动态IP黑白名单过滤 文章…

STM32芯片EXIT外部中断的配置与原理以及模板代码(标准库)

配置EXIT外部中断其实就是把GPIO刀NVIC的各个外设配置好 第一步&#xff1a;配置RCC&#xff0c;把我们涉及到的外设的时钟都打开 &#xff08;此处EXTI是默认打开的&#xff0c;而NVIC是内核外设无需配置&#xff09; 第二步&#xff1a;配置GPIO,选择端口为输入模式 第三…

大数据实验4-HBase

一、实验目的 阐述HBase在Hadoop体系结构中的角色&#xff1b;能够掌握HBase的安装和配置方法熟练使用HBase操作常用的Shell命令&#xff1b; 二、实验要求 学习HBase的安装步骤&#xff0c;并掌握HBase的基本操作命令的使用&#xff1b; 三、实验平台 操作系统&#xff1…

商用密码产品认证名录说明

《商用密码产品认证目录》是为贯彻落实《中华人民共和国密码法》&#xff0c;进一步健全完善商用密码产品认证体系&#xff0c;更好满足商用密码产业发展需要&#xff0c;根据《国家密码管理局 市场监管总局关于调整商用密码产品管理方式的公告》《市场监管总局 国家密码管理局…

uniapp微信小程序接入airkiss插件进行WIFI配网

本文可参考uniapp小程序插件 一.申请插件 微信公众平台设置页链接&#xff1a;微信公众平台 登录您的小程序微信公众平台&#xff0c;进入设置页&#xff0c;在第三方设置->插件管理->添加插件中申请AiThinkerAirkissforWXMini插件&#xff0c;申请的插件appId为【wx6…

突破自动驾驶瓶颈!KoMA:多智能体与大模型的完美融合

0.简介 本推文主要介绍了由来自北京航空航天大学的姜克谋、蔡轩和崔智勇教授等共同提出的一种名为KoMA的知识驱动的多智能体框架。论文《KoMA: Knowledge-driven Multi-agent Framework for Autonomous Driving with Large Language Models》提出了KoMA框架&#xff0c;通过结…

企业项目级IDEA编辑器设置类注释、方法注释模板(仅增加@author和@date)

文章目录 前言一 设置类注释1.1 添加模板1.2 复制配置 二 设置方法注释2.1 添加模版2.2 设置模版2.3 设置参数变量2.4 配置对应快捷键2.5 配置对应作用域2.6 使用方式 说明 前言 公司代码规范中&#xff0c;需要在标准JavaDoc注释的基础上加上作者和日期。网上虽然有很多现成的…

【HOT100第五天】搜索二维矩阵 II,相交链表,反转链表,回文链表

240.搜索二维矩阵 II 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 先动手写写最简单方法&#xff0c;二重循环。 class Solution { public:bool searchMa…

OLED透明屏在零售行业有哪些优势

OLED透明屏在零售行业具有诸多优势&#xff0c;这些优势使得它成为零售行业中一种创新且高效的展示工具。以下是对OLED透明屏在零售行业优势的详细分析&#xff1a; 1. 视觉吸引力与沉浸感 高透明度&#xff1a;OLED透明屏能够实现40%以上的透明度&#xff0c;使得屏幕后的物体…

kali搭建pikachu靶场

前言&#xff1a; 总所周知搭个网站需要有apachemysqlphp&#xff0c;Apache是一个开源的Web服务器软件&#xff0c; MySQL是一种关系型数据库管理系统&#xff08;数据库&#xff09;&#xff0c;PHP是一种在服务器上执行的脚本语言 文章内容来自&#xff1a;【黑帽编程与攻…

学习threejs,对模型多个动画切换展示

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.AnimationMixer 动画…

【再谈设计模式】适配器模式 ~接口兼容的桥梁

一、引言 在软件开发的复杂世界里&#xff0c;不同的组件、类或者系统往往有着各自独立的设计和接口定义。当需要将这些原本不兼容的部分整合在一起协同工作时&#xff0c;就像尝试将方形的榫头插入圆形的卯眼一样困难。适配器设计模式就如同一位神奇的工匠&#xff0c;能够巧妙…

光猫、路由器、交换机之连接使用(Connection and Usage of Optical Cats, Routers, and Switches)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

《深入理解 Spring MVC 工作流程》

一、Spring MVC 架构概述 Spring MVC 是一个基于 Java 的轻量级 Web 应用框架&#xff0c;它遵循了经典的 MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;将请求、响应和业务逻辑分离&#xff0c;从而构建出灵活可维护的 Web 应用程序。 在 Spring MV…

【Python小技巧】高效实现文件批量重命名

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…