5.C++动态内存管理(超全)

news2024/11/19 1:56:31

目录

1 .C/C++ 内存分布

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

3. C++内存管理方式 

3.1 new/delete操作内置类型

3.2 new和delete操作自定义类型

3.3 operator new函数

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

4. 常见面试题

4.1 malloc/free和new/delete的区别

4.2 内存泄漏


1 .C/C++ 内存分布

我们可以来看一下下面图例

注意:1. 局部指针指向的字符串,是在代码段的

           2.局部指针指向的malloc是在堆区的

           3.局部指针是在栈区的

【说明】:

1. 又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。

2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。(后面Linux会学习,现在只需要了解一下)

3. 用于程序运行时动态内存分配,堆是可以上增长的。

4. 数据段--存储全局数据和静态数据

5. 代码段--可执行的代码/只读常量。

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

这篇文章中有详细讲到  C语言动态内存管理(超详细)

1. malloc/calloc/realloc的区别?

malloc用于分配内存空间,calloc用于分配并初始化内存空间,realloc用于重新分配内存空间。它们都需要手动释放分配的内存空间,以避免内存泄漏。

2. malloc的实现原理?

malloc函数的实现原理是通过维护一个内存块链表,在堆内存中找到合适大小的空闲内存块来分配内存。当调用malloc时,会在链表中查找可用内存块,如果找到则标记为已占用并返回地址,否则向操作系统请求更多内存。malloc还考虑内存对齐,确保返回的内存地址按对齐方式分配。需要手动初始化和释放内存。

详情见glibc中malloc实现原理~

3. C++内存管理方式 

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

3.1 new/delete操作内置类型

T*  p=new T (指针类型指向new的空间)

void Test()
{
	// 动态申请一个int类型的空间
	int* ptr4 = new int;

	// 动态申请一个int类型的空间并初始化为10
	int* ptr5 = new int(10);

	// 动态申请10个int类型的空间
	int* ptr6 = new int[10];

	delete ptr4;
	delete ptr5;
	delete[] ptr6;
}

注意:new T (表示初始化)

           new T [表示连续开辟空间个数]

new和delete要匹配起来使用。

3.2 new和delete操作自定义类型

#include<iostream>
using namespace std;
class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A():" << this << endl;
	}
	~A()
	{
		cout << "~A():" << this << endl;
	}
private:
	int _a;
};
// new/delete 和 malloc/free最大区别是 new/delete对于
// 【自定义类型】除了开空间还会调用构造函数和析构函数

int main()
{
	A* p1 = (A*)malloc(sizeof(A));
	A* p2 = new A(1);
	free(p1);
	delete p2;

	A* p5 = (A*)malloc(sizeof(A) * 10);
	A* p6 = new A[10];
	free(p5);
	delete[] p6;

}

打印出来的部分效果如图

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

3.3 operator new函数

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

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

通过反汇编的观察可以发现,new的定义像是一个套娃的包装实现

new(operator new( malloc

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

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

使用格式:

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

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

使用场景:

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

// 定位new/replacement new
int main()
{
 // p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行
 A* p1 = (A*)malloc(sizeof(A));
 new(p1)A; // 注意:如果A类的构造函数有参数时,此处需要传参
 p1->~A();
 free(p1);
}

4. 常见面试题

4.1 malloc/free和new/delete的区别

malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放

不同的地方是(6点):

\malloc/freenew/delete
类型函数操作符
初始化不可以可以
申请空间大小手动计算[ 对象个数]
转换需要强转后面跟有空间类型
失败时返回NULL(要判空)捕获异常
自定义类型对象只会开辟空间会调用构造函数完成初始化

4.2 内存泄漏

1. 什么是内存泄漏及危害  

什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不 是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死

  • 普通程序,内存泄露,影响不大,进程正常结束会释放资源
  • 长期运行的程序,内存泄露危害很大。----游戏服务,电商服务

2 内存泄漏分类(了解)

C/C++程序中一般我们关心两种方面的内存泄漏:

~堆内存泄漏(Heap leak)

堆内存指的是程序执行中依据须要分配通过malloc / calloc / realloc / new等从堆中分配的一块内存, 用完后必须通过调用相应的 free或者delete 删掉。假设程序的设计错误导致这部分内存没有被释放,那 么以后这部分空间将无法再被使用,就会产生Heap Leak。

~系统资源泄漏

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

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

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

因此写代码时一定要小心,尤其是动态内存操作时,一定要记着释放。但有些情况下总是防不胜防,简单的 可以采用上述方式快速定位下。如果工程比较大,内存泄漏位置比较多,不太好查时一般都是借助第三方内 存泄漏检测工具处理的。

  • 在linux下内存泄漏检测:linux下几款内存泄漏检测工具
  • 在windows下使用第三方工具:VLD工具说明
  • 其他工具:内存泄漏工具比较

4. 如何避免内存泄漏

1. 工程前期良好的设计规范,养成良好的编码规范,申请的内存空间记着匹配的去释放。ps:这个理想状态。但是如果碰上异常时,就算注意释放了,还是可能会出问题。需要下一条智能指针来管理才有保证。

2. 采用RAII思想或者智能指针来管理资源。

3. 有些公司内部规范使用内部实现的私有内存管理库。这套库自带内存泄漏检测的功能选项。

4. 出问题了使用内存泄漏工具检测。ps:不过很多工具都不够靠谱,或者收费昂贵。

总结一下: 内存泄漏非常常见,解决方案分为两种:

1、事前预防型。如智能指针等。

2、事后查错型。如泄漏检测工具

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

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

相关文章

开发一个语音聊天社交app小程序H5需要多少钱?

社交&#xff0c;即时通讯APP系统。如何开发一个社交App||开发一个即时通信应用是一项复杂而充满挑战的任务&#xff0c;需要考虑多个技术、开发时间和功能方面的因素。以下是一个概要&#xff0c;描述了从技术、开发时间和功能角度如何开发这样的应用&#xff1a; 1. 技术要点…

Centos7.9系统MySQL5.7.32升级为5.7.44(生成环境操作)

1.背景 由于客户进行等保漏扫和渗透&#xff0c;生成环境mysql数据库被扫描出了 高危漏洞。 如图&#xff1a;部分漏洞 查看漏洞详细信息&#xff0c;建议升级到指定版本解决&#xff1a; 说明&#xff1a; 本文仅适合使用当前数据库为 RPM 安装方式 2.升级前准备 查看环…

STM32-HAL库12-STM32F407VGT6的PWM主从定时器,发送指定数量脉冲

STM32-HAL库12-STM32F407VGT6的PWM主从定时器&#xff0c;发送指定数量脉冲 一、所用材料 STM32F407VGT6自制双伺服电机控制板&#xff1b; 一川A1系列伺服电机驱动器&#xff08;电0.73KW电机&#xff09;&#xff1b; 二、所学内容 实现PWM发送指定个数脉冲&#xff0c;以…

Noisy:一款功能强大的DNS和HTTPS网络流量噪声生成工具

关于Noisy Noisy是一款功能强大的DNS和HTTP/S网络流量噪音生成工具&#xff0c;该工具基于Python开发&#xff0c;可以帮助广大研究人员在进行常规网络浏览时&#xff0c;在后台生成随机的HTTP/DNS网络流量噪声&#xff0c;并以此来提升网络通信数据的安全性和隐蔽性。 支持的…

Hikyuu-教程-如何利用 FINANCE 指标计算市盈率

本篇主要讲解如何利用 FINANCE 指标计算市盈率&#xff0c;其他市净率等指标可以参考此文实现。 获取历史财务字段信息 调用 sm.get_history_finance_all_fields() 方法获取历史财务信息对应字段的索引号和名称 In [2]: sm.get_history_finance_all_fields() Out[2]: [(0, 基…

Bert基础(二十一)--Bert实战:文本摘要

一、介绍 1.1 文本摘要简介 文本摘要&#xff08;Text Summarization&#xff09;&#xff0c;作为自然语言处理&#xff08;NLP&#xff09;领域的一个分支&#xff0c;其核心目标是从长篇文档中提取关键信息&#xff0c;并生成简短的摘要&#xff0c;以提供对原始内容的高度…

Rust中的并发性:Sync 和 Send Traits

在并发的世界中&#xff0c;最常见的并发安全问题就是数据竞争&#xff0c;也就是两个线程同时对一个变量进行读写操作。但当你在 Safe Rust 中写出有数据竞争的代码时&#xff0c;编译器会直接拒绝编译。那么它是靠什么魔法做到的呢&#xff1f; 这就不得不谈 Send 和 Sync 这…

Apache SeaTunnel k8s 集群模式 Zeta 引擎部署指南

SeaTunnel提供了一种运行Zeta引擎(cluster-mode)的方法&#xff0c;可以让Kubernetes在本地运行Zeta引擎&#xff0c;实现更高效的应用程序部署和管理。在本文中&#xff0c;我们将探索SeaTunnel k8s运行zeta引擎(cluster-mode模式)的更多信息&#xff0c;了解如何更好地利用Ze…

大数据技术就业和发展前景怎么样

大数据技术的就业和发展前景极为乐观&#xff0c;具有行业需求旺盛、就业多样性、可持续发展潜力等特点&#xff0c; 上大学网 &#xff08;www.sdaxue.com&#xff09;整理出了大数据技术的就业和发展前景以下几个关键趋势&#xff0c;供大家参考&#xff01; 行业需求旺盛&…

[华为OD] C卷 5G网络 现需要在某城市进行5G网络建设,已经选取N个地点设置5G基站 200

题目 现需要在某城市进行5G网络建设&#xff0c;已经选取N个地点设置5G基站&#xff0c;编号固定为1到N,接 下来需要各个基站之间使用光纤进行连接以确保基站能互联互通&#xff0c;不同基站之间架设光纤的成 本各不相同&#xff0c;且有些节点之间已经存在光纤相连&#…

数据仓库Data Warehouse

数据仓库Data Warehouse 数仓是一种思想,数仓是一种规范,数仓是一种解决方案 1. 数据处理方式 数据处理大致可以分成两大类: 联机事务处理OLTP(on-line transaction processing)联机分析处理OLAP(On-Line Analytical Processing)1.1. OLTP OLTP的全称是On-line Transa…

Unity添加证件

目录 1.问题描述&#xff1a;2.解决方法&#xff1a;小结&#xff1a; 1.问题描述&#xff1a; 2.解决方法&#xff1a; 登录后跳转打开 添加证件 选择个人证件 小结&#xff1a; 关注我给大家分享更多有趣的知识&#xff0c;以下是个人公众号&#xff0c;提供 ||代码兼职||…

基于 React 的图形验证码插件

react-captcha-code NPM 地址 &#xff1a; react-captcha-code - npm npm install react-captcha-code --save 如下我自己的封装&#xff1a; import Captcha from "react-captcha-code";type CaptchaType {captchaChange: (captchaInfo: string) > void;code…

利用大型语言模型提升数字产品创新:提示,微调,检索增强生成和代理的应用

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【漏洞复现】科达 MTS转码服务器 任意文件读取漏洞

0x01 产品简介 科达 MTS转码服务器是一款专业的视频转码设备&#xff0c;采用了高性能的硬件配置和先进的转码技术&#xff0c;能够实现高效、高质量的视频转码。 0x02 漏洞概述 科达 MTS转码服务器存在任意文件读取漏洞&#xff0c;攻击可以通过该漏洞读取服务器任意敏感信…

ChatGPT向付费用户推“记忆”功能,可记住用户喜好 | 最新快讯

4月30日消息&#xff0c;人工智能巨头OpenAI宣布&#xff0c;其开发的聊天机器人ChatGPT将在除欧洲和韩国以外的市场全面上线“记忆”功能。这使得聊天机器人能够“记住”ChatGPT Plus付费订阅用户的详细信息&#xff0c;从而提供更个性化的服务。 OpenAI早在今年2月就已经宣布…

java同步大量数据到本地数据库方法总结

最近在做一个需求&#xff0c;就是我需要对三方接口调用的数据存放到本地的数据库里的数据表里面。那么一开始我就是直接一条一条save&#xff0c;结果发现耗时非常严重&#xff0c;后面我就进行了改进。就是分批次去同步或者分批次去异步。 现在我直接贴出我写的代码&#xf…

PG后台进程个人解读和与oracle 的比较

1.background writer &#xff08;后台写进程&#xff09; 与OracleDBWR进程工作原理类似&#xff0c;都是负责把缓冲区里面的脏块写到数据文件中&#xff0c;写的目的有两个&#xff1a; 1.为了保存数据。 2.为了释放内存空间。 触发background writer 写的条件&#xff1a…

Virtualbox--下载指定版本

一、前言 下载Virtualbox7.0.10&#xff0c;可参考《Virtualbox–下载指定版本》 Virtualbox7.0.10具体安装步骤&#xff0c;可参考《Virtualbox7.0.10的安装步骤》 Virtualbox7.0.10创建虚拟机&#xff0c;可参考《Virtualbox7.0.10–创建虚拟机》 Virtualbox7.0.10安装Ubuntu…

GPT3 终极指南(二)

原文&#xff1a;zh.annas-archive.org/md5/6de8906c86a2711a5a84c839bec7e073 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第五章&#xff1a;GPT-3 作为企业创新的下一步 当一个新的创新或技术转变发生时&#xff0c;大公司通常是最后一个采纳的。它们的等级结构…