内存 管理

news2024/11/27 16:46:10

内存管理

  • c/c++中内存分布
  • sizeof 与 strlen
  • c 语言中动态内存管理方式
    • malloc
    • calloc
    • realloc
  • c++ 中动态内存管理
    • new 与 delete
    • 自定义类型空间的动态分配
    • new 与 delete 的实现
  • operator new 与 operator delete
  • 基本概念辨识
    • malloc/free 与 new/delete 区别 *****
    • 内存泄漏

c/c++中内存分布

c/c++ 中程序内存的区域划分:

在这里插入图片描述

分析下列代码中变量的存储地址:

int glob = 1;
static int staglob = 1;

int main()
{
	static int a = 1;
	int b = 2;

	int num1[10] = { 1,2,3,4 };
	char str1[] = "abcd";
	const char* pchar = "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);
	return 0;
}

存储结构分析
在这里插入图片描述

sizeof 与 strlen

sizeof:计算类型大小

在这里插入图片描述

strlen:计算字符长度,遇到 \0 结束

在这里插入图片描述

但是考虑一个问题:

为什么在 malloc 、calloc、realloc 了三个变量空间之后,只进行释放(free)了两次?

这就是我们接下来要讨论的一个问题。

c 语言中动态内存管理方式

malloc

void malloc( size_t size );
动态申请空间,但不进行初始化操作
由于返回值为 void
类型,因此在使用时需要进行类型强转
空间使用结束需要手动 free,否则会造成内存泄漏

malloc 申请到的空间内容为随机值:

在这里插入图片描述

calloc

void calloc( size_t num, size_t size );
动态申请空间,并将申请到的空间初始化为 0
由于返回值为 void
类型,因此在使用时需要进行类型强转
空间使用结束需要手动 free,否则会造成内存泄漏

calloc 申请到的空间内容会初始化为 0:

在这里插入图片描述

realloc

void *realloc( void *memblock, size_t size );
在原有的空间基础上进行空间的重新申请,并会释放回收原有的空间,不会进行初始化操作
空间使用结束需要手动 free,否则会造成内存泄漏

realloc 重新开辟新空间并会释放掉旧空间,不会进行初始化:

在这里插入图片描述

realloc 重新分配空间之后,会自动释放掉原有空间,因此只需要空间释放一次,并且在重新分配空间时会保持相应位置空间内容不变(扩容:原有大小内容不变,后序新空间为随机值;缩小容量:空间内容与原内容保持一致)

在这里插入图片描述

c++ 中动态内存管理

因为 C++ 兼容 C语言,因此在 C++ 语言当中,依旧可以使用 malloc 、calloc、 realloc 来进行动态内存管理,并且在使用结束之后手动 free 释放空间,避免造成内存泄漏。

new 与 delete

C++ 中也常通过 new 和 delete 来进行动态内存的管理:

new T:申请单个 T 类型的空间
new T[N]:申请N个T类型的一段连续空间

new T(a):动态申请一个 T 类型空间,并初始化为 a
new T[n]{…}:动态申请 n 个 T 类型的连续空间,并在 {} 中进行初始化操作

delete 变量名 :释放单个空间
delete[] 变量名:释放连续空间

在使用 new 与 delete 进行动态内存管理时候要注意对应:
申请单个空间 new T —> 释放单个空间 delete;
申请连续空间 new T[] ---->释放连续空间 delete[];

int main()
{
	int* p1 = new int; //申请单个 int 空间
	int* p2 = new int[10];  //申请 10 个 连续的 int 类型空间
	
	//初始化
	int* p3 = new int(10);
	int* p4 = new int[10]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };


	//空间的释放

	delete p1;
	delete[] p2;     //释放空间应与创建空间匹配----连续的空间
	delete p3;
	delete[] p4;      //释放空间应与创建空间匹配----连续的空间
	 
	
	return 0;
}

由此可见,C++中动态内存管理 new / delete 不需要进行类型的强转

自定义类型空间的动态分配

(1)使用传统的 C 语言 malloc / free 进行动态内存的管理:

class Test {
public:
	Test() :_data(1)
	{
		cout << "Test()" << this << endl;
	}
	~Test()
	{
		cout << "~Test()" << this << endl;
	}
private:
	int _data;
};

int main()
{
	Test* p1 = (Test*)malloc(sizeof(Test));       //单个 Test 类型空间
	free(p1);

	Test* p2 = (Test*)malloc(sizeof(Test) * 10);   //连续 10 个 Test 类型空间
	free(p2);
	return 0;
}

在这里插入图片描述

(2)使用 C++ 中 new / delete 进行动态内存管理:

class Test {
public:
	Test() :_data(1)
	{
		cout << "Test()" << this << endl;
	}
	~Test()
	{
		cout << "~Test()" << this << endl;
	}
private:
	int _data;
};

int main()
{
	Test* p1 = new Test;  //申请单个 Test 空间
	delete p1;   //释放单个空间

	Test* p2 = new Test[10]; //申请连续10个 Test 空间
	delete[] p2;   //释放连续空间

	return 0;
}

在这里插入图片描述

对于自定义类型的动态内存管理,倘若没有进行匹配释放空间则会造成程序崩溃或内存泄漏:

在这里插入图片描述

new 与 delete 的实现

在申请自定义类型的空间时,new 会调用相应的构造函数对空间进行初始化操作,delete 会调用相应的析构函数进行资源的清理:

在这里插入图片描述

operator new 与 operator delete

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

(一)operator new

new 申请空间,要么申请成功,要么报错,因此不需要进行判空。

new 申请新空间(自定义类型):
(1)内置类型直接调用 operator new 申请空间;
(2)自定义类型空间,先在堆上进行申请空间,其次调构造函数对空间进行初始化操作。

在这里插入图片描述
在这里插入图片描述

该函数实际上是通过 malloc 来申请空间(operator new 实际上是对 malloc 的封装),当 malloc 申请空间成功直接返回;申请失败,会进行相应不足应对措施:
检测是否是空间不足------若提供空间不足应对措施,则执行并继续 malloc;若没有提供则会发出 bad_alloc 类型异常。

在这里插入图片描述

通过反汇编来查看底层调用:

在这里插入图片描述
在这里插入图片描述

(二)operator delete

该函数实际上是通过 free 进行释放空间的。

在这里插入图片描述

delete 释放空间:
(1)若是内置类型,直接将空间释放;
(2)若是自定义类型空间,先调用析构函数进行资源的清理,其次将空间清理掉。

在这里插入图片描述
在这里插入图片描述

通过反汇编来查看底层调用:

在这里插入图片描述

内置类型创建连续空间,则会多次调用构造函数对空间进行初始化;
内置类型释放连续空间,则会多次调用析构函数对空间资源进行清理;

在这里插入图片描述

operator new 与 operator delete 支持重载,但一般情况下不用。

基本概念辨识

malloc/free 与 new/delete 区别 *****

相同点:

两者都是从堆上进行空间的申请,并且需要手动进行释放;

不同点:

(1)malloc/free 是函数(需要头文件),new/delete 是操作符(不需要头文件);

(2)malloc 申请的空间不会进行初始化(内容为随机值),new 可以进行初始化;

(3)malloc 申请空间时,需要手动计算空间大小并进行传参,new 只需要在其后跟上空间类型即可;

(4)malloc 返回值为 void* ,因此在使用时候需要进行类型强转,new 不需要;

(5)malloc 申请空间失败时返回 NULL,因此需要判空,new不需要—直接报错;

(6)申请自定义类型对象时,malloc/free 指挥开辟空间,不会调用构造函数与析构函数,而 new 在申请空间后会调用自定义类型对象的构造函数进行对象初始化,delete 在释放空间前会调用析构函数完成对象空间中的资源清理工作。

内存泄漏

内存泄漏:

指的是因为疏忽/错误造成程序未能释放已经不能使用的内存的情况。

内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的操作,因而造成了内存的浪费。

内存泄漏的危害:

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

内存泄漏分类:

(1)堆内存泄漏

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

(2)系统资源泄漏

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

欢迎评论留言哈~~~

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

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

相关文章

手把手教你:CSS + JS实现文本交替

1. Koa 中间件 Koa 的中间件通过一种更加传统的方式进行级联&#xff0c;摒弃了以往 node 频繁的回调函数造成的复杂代码逻辑。使用异步函数&#xff0c;我们可以实现"真正" 的中间件。与之不同&#xff0c;当执行到 yield next 语句时&#xff0c;Koa 暂停了该中间…

Qt 在linux上检测内存泄漏,用valgrind的问题

我在ubuntu上装了Qt5.15.2, 打开我的项目后&#xff0c;准备检测内存泄漏问题。 此时&#xff1a; 内存检测工具都是可用状态&#xff0c;但点击内存检测后&#xff0c;进度条走完后&#xff0c;就结束了。项目都没启动起来&#xff0c;这怎么检测内存问题&#xff1f; 然后&…

11月30日(第二天)

序列化&#xff1a;implements Serializable&#xff0c;public final static Long SeriaVersionUid 1L;MP的使用步骤&#xff1a;在BookBO类上使用TableName(“表名")去关联&#xff0c;在字段上使用TableId&#xff0c;TableField进行字段关联。(最好新建一个BookVO类,…

嫦娥五号探测器详细介绍

嫦娥五号&#xff08;Change 5&#xff09;&#xff0c;即嫦娥五号探测器&#xff0c;是由中国空间技术研究院研制的中国首个实施无人月面取样返回的航天器&#xff0c;是完成中国探月工程重大科技专项“绕、落、回”三步走发展战略最后一步的关键任务。 中国探月工程三步走 嫦…

Linux 主机间ssh相互免密

Linux 主机间ssh相互免密两步实现ssh主机免密详细教程请往下看主机间ssh相互免密 —— 方法一主备两台未配置密钥主机作为测试生成公私密钥拷贝公钥到目标主机ssh免密测试主机间ssh相互免密——方法二实验准备分发密钥对免密测试MobaXterm免密登录服务器&#xff08;以ecs-4207…

SAP中的PI接口

文章目录1 Pi overall2 Create pi process3 Inbound interface4 Outbound interface5 Matter need attention6 Pi test7 View log8 Transport CTS1 Pi overall What is the pi ? Pi is Sap’s middle software . it is interacted with SAP an external system. 2 Create p…

【Python】Python 中实现数据序列化

文章目录一、前言二、为什么要进行序列化三、Python 中的数据序列化1. json模块2. pickle模块3. shelve模块4. 总结参考链接一、前言 首先&#xff0c;要了解什么是序列化&#xff0c;请参考我的另一篇文章&#xff1a;序列化与反序列化介绍 本文主要介绍 Python 中的数据序列…

i.MX 6ULL 驱动开发 二十七:块设备

参考&#xff1a;【块设备】通用块层 struct bio 详解 | zzm (aliez22.github.io) 一、Linux 中块设备驱动框架 二、块设备基本概念 1、扇区的概念来自硬件&#xff0c;扇区是硬件最小操作单位。 2、块的概念来自文件系统&#xff0c;是文件系统数据处理的最小单位。 3、段…

django 开启CSRFtoken校验,以及postman实现问题

1.0 Django默认的CSRFtoken 表现&#xff1a; 后端使用的是Django的表单验证 post请求携带参数的问题 2.0 先处理post请求携带数据的csrfmiddlewaretoken 在登录界面 在input输入框中隐藏&#xff0c;所以需要提取input的value值&#xff0c;在【tests】脚本中进行提取&…

小样本关系分类(原型学习):Better Few-Shot Relation Extraction with Label Prompt Dropout

Better Few-Shot Relation Extraction with Label Prompt Dropout core idea 在小样本关系分类中&#xff0c;prompt信息是relation name是信息&#xff0c;这篇文章为了保持train和test的一致性&#xff0c;将train中的一些relation name信息删除掉了。&#xff08;相反&…

linux应用移植问题

背景 公司设备降成本&#xff0c;设备运行平台从armv7架构mpu换成了armv5架构的mpu&#xff0c;应用移植过程都挺顺利的&#xff0c;只是牵涉到一个引用外部库的应用时&#xff0c;运行该应用到引用库中的函数时&#xff0c;应用抛出illegal instrution异常。 问题分析 初步…

HTML(超文本标记语言)

HTML(超文本标记语言) 网页的基本信息 、等成对的标签&#xff0c;分别叫**开放标签**和**闭合标签**&#xff0c;单独呈现的标签(空元素)&#xff0c;如&#xff1b;意为用 / 来关闭空元素 DOCTYPE&#xff1a;告诉浏览器&#xff0c;我们要使用什么规范 head&#xff1a;代…

Jenkins安装与配置Windows11系统

目录 Jenkins安装 一、下载 官网地址&#xff1a;Jenkins download and deployment 点击LTS&#xff08;长期稳定版&#xff09;下的Windows 二、安装 基本就是一路Next即可 三、配置 访问地址 http://localhost:8080/&#xff0c;会出现如下界面&#xff1a; 安装 注&…

Redis实战——优惠券秒杀(一人一单业务)

需求&#xff1a;修改秒杀业务&#xff0c;要求同一个优惠券&#xff0c;一个用户只能下一单 我们只需要在增加订单之前&#xff0c;拿用户id和优惠券id判断订单是否已经存在&#xff0c;如果存在&#xff0c;说明用户已经购买。 代码实现&#xff1a; package com.hmdp.serv…

狂神说Go语言学习笔记(二)

一、匿名变量 匿名变量的特点是一个下划线 “_”&#xff0c;它本身就是一个特殊的标识符。它可以像其他标识符那样用于变量的声明或赋值&#xff08;任何类型都可以赋值给它&#xff09;&#xff0c;但任何赋给这个标识符的值都将被抛弃&#xff0c;因此这些值不能在后续的代…

共享雨伞app开发,提高资源利用率

共享经济无疑是当下热门行业之一&#xff0c;生活中随处可见的共享自行车、共享汽车、共享充电宝等一系列设备都是共享经济的产物。互联网时代下的共享经济已经呈现出多元化的发展趋势&#xff0c;其中在日常出行方面&#xff0c;共享雨伞的出现可以很好的解决用户偶遇的突发天…

Centos7 + kubenetes 一键安装实战

1. kubernetes部署环境要求 一台或多台机器&#xff0c;操作系统CentOS7.x-86_x64硬件配置&#xff1a;内存2GB或2G&#xff0c;CPU 2核或CPU 2核集群内各个机器之间能相互通信集群内各个机器可以访问外网&#xff0c;保证网络畅通&#xff08;最好能访问谷歌&#xff09;,需要…

【STM32笔记】HAL库中的SPI传输(可利用中断或DMA进行连续传输)

【STM32笔记】HAL库中的SPI传输&#xff08;可利用中断或DMA进行连续传输&#xff09; SPI 是英语Serial Peripheral interface的缩写&#xff0c;顾名思义就是串行外围设备接口。是Motorola(摩托罗拉)首先在其MC68HCXX系列处理器上定义的。 SPI&#xff0c;是一种高速的&…

优秀软件测试报告

Document number 文档编号 Confidentiality level 密级 Test Report-01 [绝密/秘密/内部公开] Document version 文档版本 Total 10 pages 共 10 页 V1.0 测试报告 Prepared by 拟制 Date 日期 yyyy-mm-dd Reviewed by 评审人 Date 日期 yyyy-mm-dd Approved b…

CSS基础(超详解)

目录 1 css基础知识 1.1基础知识 1.1 概述 1.2 优势 1.3应用css的步骤 1.2 css基本语法 1.3 css使用方法 1.3.1 内嵌样式 1.3.2 内部样式 1.3.3 外部样式 1.3.4 使用import引入外部样式文件 1.3.5 叠层样式优先级 1.3.6 注释 2 CSS选择器 2.1 元素选择器 2.2 类…