当前位置: 首页 > news >正文

C++标准模板(STL)- 低层内存管理 - 解分配函数 (operator delete, operator delete[])

低层内存管理


new 表达式是创建拥有动态存储期对象或对象数组的仅有方式,即它们拥有不受制于创建所它们在的作用域的生存期。 new 表达式通过调用分配函数获得存储。 delete 表达式销毁最终导出对象或通过 new 表达式创造的数组,然后调用解分配函数。默认分配函数和默认解分配函数,及与之关联的函数、类型及对象声明于头文件 <new> 。

解分配函数

operator delete, 
operator delete[]

定义于头文件 <new>

可替换通常解分配函数

void operator delete  ( void* ptr ) throw();

(1)(C++11 前)

void operator delete  ( void* ptr ) noexcept;

(C++11 起)

void operator delete[]( void* ptr ) throw();

(2)(C++11 前)

void operator delete[]( void* ptr ) noexcept;

(C++11 起)

void operator delete  ( void* ptr, std::align_val_t al ) noexcept;

(3)(C++17 起)

void operator delete[]( void* ptr, std::align_val_t al ) noexcept;

(4)(C++17 起)

void operator delete  ( void* ptr, std::size_t sz ) noexcept;

(5)(C++14 起)

void operator delete[]( void* ptr, std::size_t sz ) noexcept;

(6)(C++14 起)

void operator delete  ( void* ptr, std::size_t sz,
                        std::align_val_t al ) noexcept;

(7)(C++17 起)

void operator delete[]( void* ptr, std::size_t sz,
                        std::align_val_t al ) noexcept;

(8)(C++17 起)

可替换布置解分配函数

void operator delete  ( void* ptr, const std::nothrow_t& tag ) throw();

(9)(C++11 前)

void operator delete  ( void* ptr, const std::nothrow_t& tag ) noexcept;

(C++11 起)

void operator delete[]( void* ptr, const std::nothrow_t& tag ) throw();

(10)(C++11 前)

void operator delete[]( void* ptr, const std::nothrow_t& tag ) noexcept;

(C++11 起)

void operator delete  ( void* ptr, std::align_val_t al,
                        const std::nothrow_t& tag ) noexcept;

(11)(C++17 起)

void operator delete[]( void* ptr, std::align_val_t al,
                        const std::nothrow_t& tag ) noexcept;

(12)(C++17 起)

不分配布置解分配函数

void operator delete  ( void* ptr, void* place ) throw();

(13)(C++11 前)

void operator delete  ( void* ptr, void* place ) noexcept;

(C++11 起)

void operator delete[]( void* ptr, void* place ) throw();

(14)(C++11 前)

void operator delete[]( void* ptr, void* place ) noexcept;

(C++11 起)

用户定义的布置解分配函数

void operator delete  ( void* ptr, args... );

(15)

void operator delete[]( void* ptr, args... );

(16)

类特定通常解分配函数

void T::operator delete  ( void* ptr );

(17)

void T::operator delete[]( void* ptr );

(18)

void T::operator delete  ( void* ptr, std::align_val_t al );

(19)(C++17 起)

void T::operator delete[]( void* ptr, std::align_val_t al );

(20)(C++17 起)

void T::operator delete  ( void* ptr, std::size_t sz );

(21)

void T::operator delete[]( void* ptr, std::size_t sz );

(22)

void T::operator delete  ( void* ptr, std::size_t sz, std::align_val_t al );

(23)(C++17 起)

void T::operator delete[]( void* ptr, std::size_t sz, std::align_val_t al );

(24)(C++17 起)

类特定布置解分配函数

void T::operator delete  ( void* ptr, args... );

(25)

void T::operator delete[]( void* ptr, args... );

(26)

类特定销毁解分配函数

void T::operator delete(T* ptr, std::destroying_delete_t);

(27)(C++20 起)

void T::operator delete(T* ptr, std::destroying_delete_t,
                        std::align_val_t al);

(28)(C++20 起)

void T::operator delete(T* ptr, std::destroying_delete_t, std::size_t sz);

(29)(C++20 起)

void T::operator delete(T* ptr, std::destroying_delete_t,
                        std::size_t sz, std::align_val_t al);

(30)(C++20 起)

解分配先前由匹配的 operator new 所分配的存储。这些解分配函数为 delete 表达式与 new 表达式所调用,以在析构(或构造失败)拥有动态存储期的对象后解分配内存。它们亦可用常规函数调用语法调用。

1) 为 delete 表达式所调用,以解分配先前为单对象分配的存储。此函数的标准库实现的行为未定义,除非 ptr 是空指针或是先前从 operator new(size_t) 或 operator new(size_t, std::nothrow_t) 的标准库实现获得的指针。

2) 为 delete[] 表达式所调用,以解分配先前为对象数组分配的存储。此函数的标准库实现的行为未定义,除非 ptr 是空指针或是先前从 operator new[](size_t) 或 operator new[](size_t, std::nothrow_t) 的标准库实现获得的指针。

3,4) 同 (1,2) ,除了若对齐要求超出 __STDCPP_DEFAULT_NEW_ALIGNMENT__ 才被调用

5,6) 若提供用户定义重载,则取代 (1-2) 得到调用,除了在删除不完整类型的对象、非类类型的数组和可平凡析构类类型的数组时,调用 (1-2) 还是 (5-6) 是未指定的。内存分配器可用给定的大小变得更高效。标准库实现等同于 (1-2) 。

7,8) 同 (5-6) ,除了若对齐要求超出 __STDCPP_DEFAULT_NEW_ALIGNMENT__ 才被调用

9) 若对象的构造函数抛出异常,则为不抛出的单对象 new 表达式所调用。标准库实现表现同 (1)

10) 若任何对象的构造函数抛出异常,则(在执行数组中已成功构造的所有对象的析构函数后)为不抛出的数组 new[] 表达式所调用。标准库实现表现同 (2)

11,12) 同 (9,10) ,除了若对齐要求超出 __STDCPP_DEFAULT_NEW_ALIGNMENT__ 才被调用

13) 若对象的构造函数抛出异常,则为标准单对象布置 new 表达式所调用。此函数的标准库实现不做任何事。

14) 若任何对象的构造函数抛出异常,则为布置 new 表达式的数组形式(在执行数组中已成功构造的所有对象的析构函数后)所调用。此函数的标准库实现不做任何事。

15) 若定义,则为拥有匹配签名的自定义单对象布置 new 表达式调用,若对象构造函数抛出异常。若定义类特定版本 (25) ,则类特定版本优先于 (9) 调用。若用户既不提供 (25) 又不提供 (15) ,则不调用解分配函数。

16) 若定义,则为拥有匹配签名的布置 new[] 表达式自定义数组形式(在执行数组中已成功构造的所有对象的析构函数后)调用,若任何对象的构造函数抛出异常。若定义类特定版本 (16) ,则类特定版本优先于 (10) 调用。若用户既不提供 (26) 又不提供 (16) ,则不调用解分配函数。

17) 若定义,则为通常单对象 delete 表达式调用,若在解分配一个 T 类型对象。

18) 若定义,则为通常数组 delete[] 表达式调用,若在解分配 T 类型对象的数组。

19,20) 若定义,则优先于 (17,18) 调用,若对齐要求超出 __STDCPP_DEFAULT_NEW_ALIGNMENT__

21) 若定义,且若未定义 (17) ,则为通常单对象 delete 表达式调用,若在解分配一个 T 类型对象。

22) 若定义,且若未定义 (18) ,则为通常数组 delete[] 表达式调用,若在解分配 T 类型对象的数组。

23,24) 若定义,且若未定义 (19,20) ,则优先于无对齐成员调用,若对齐要求超出 __STDCPP_DEFAULT_NEW_ALIGNMENT__.

25) 若定义,则为拥有匹配签名的自定义单对象布置 new 表达式调用,若对象构造函数抛出异常。若不提供此函数,亦不提供匹配的 (15) ,则不调用解分配函数。

26) 若定义,则为拥有匹配签名的自定义布置 new[] 表达式的数组形式(在执行数组中已成功构造的所有对象的析构函数后)调用,若任何对象的构造函数抛出异常。若不提供此函数,亦不提供匹配的 (16) ,则不调用析构函数。

27-30) 若定义,则 delete 表达式在调用 operator delete 前不对 *p 执行析构函数。取而代之地,变为由此用户定义的 operator delete 负责直接调用析构函数,例如用 p->~T(); 。

通常(非布置)解分配函数的具对齐和不具对齐重载之间的重载决议准确细节见 delete 表达式。

(C++17 起)

所有情况下,若 ptr 是空指针,则标准库解分配函数不做任何事。若传递给标准库解分配函数的指针不是从对应的标准库分配函数取得者,则行为未定义。

在标准库解分配函数返回后,所有引用到被解分配存储的任何部分的指针都变为非法。

已因此方式变为非法的指针的任何使用,即使是复制指针值到另一指针变量,都是未定义行为。

(C++14 前)

通过已因此方式变为非法的指针解引用,以及将它传递给解分配函数(双重 delete )是未定义行为。任何其他使用是实现定义的。

(C++14 起)

参数

ptr-指向要解分配的内存块的指针或空指针
sz-传递给匹配的分配函数的 size
place-用作匹配的布置 new 中布置参数的指针
tag-匹配不抛出 operator new 所用标签的重载消歧义标签
al-被分配的对象或数组元素的对齐
args-匹配布置分配函数的任意参数(可包含 std::size_t 与 std::align_val_t )

返回值

(无)

异常

15-30) 容许用户定义的解分配函数抛异常。

(C++11 前)

15-30) 所有解分配函数均为 noexcept(true) ,除非在声明中另外说明。若解分配函数以抛异常终止,则行为未定义,即使以 noexcept(false) 声明它。

(C++11 起)

全局替换

可替换解分配函数 (1-10) 在每个翻译单元隐式声明,即使不包含 <new> 头文件。这些函数是可替换的:定义于程序任何位置、任何头文件的用户提供的拥有相同签名的非成员函数,会为整个程序替换对应的隐式版本。其声明不必可见。

若程序中提供多于一个替换,或若替换声明有 inline 指定符,则行为未定义,若替换声明于异于全局命名空间的命名空间,或若它定义为在全局作用域的 static 非成员函数,则程序为病态。

nothrow 版本 (9,10) 的标准库实现直接调用抛出版本 (1,2) 。具大小解分配函数 (5-8) 的标准库实现直接调用对应的不具大小解分配函数 (1-4) 。不具大小的抛出数组形式 (2,4) 的标准库实现直接调用对应的单对象形式 (1,3) 。

故而,替换抛出的单对象解分配函数 (1,3) 足以处理所有解分配。

(C++11 起)

相关文章:

C++标准模板(STL)- 低层内存管理 - 解分配函数 (operator delete, operator delete[])

低层内存管理 new 表达式是创建拥有动态存储期对象或对象数组的仅有方式&#xff0c;即它们拥有不受制于创建所它们在的作用域的生存期。 new 表达式通过调用分配函数获得存储。 delete 表达式销毁最终导出对象或通过 new 表达式创造的数组&#xff0c;然后调用解分配函数。默认…...

LeetCode 热题 HOT 100 (025/100)【宇宙最简单版】

【二叉树】No. 0124 二叉树中的最大路径和 【困难】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你…...

【mysql 第三篇章】一条 update语句是怎么持久化到磁盘上的?

首先看一下这个 SQL 语句你会不会写? 下面是说明执行这个 SQL 语句&#xff0c;数据库底层做了什么操作。 update users set namexxx where id10;在引擎要执行更新语句的时候&#xff0c;比如更新 id10 这行数据时&#xff0c;他会先查看数据在缓冲池中是否存在&#xff0c;如…...

深入探索大模型:从基础到实践,开启AI之旅

摘要&#xff1a; 在人工智能领域&#xff0c;大模型技术正成为推动创新和进步的关键力量。对于初学者而言&#xff0c;掌握大模型的基本概念、理论和技术是至关重要的。 本文将为你提供一个全面的学习路线&#xff0c;帮助你从基础知识出发&#xff0c;逐步深入到大模型的实践…...

题解:力扣1567 - 返回乘积为正数的最长子数组

问题描述 给定一个整数数组 nums&#xff0c;找出乘积为正数的最长子数组的长度。这里的子数组定义为连续元素的序列&#xff0c;乘积为正数指子数组中正数的个数必须大于负数的个数。 解题思路 为了解决这个问题&#xff0c;我们可以使用两个数组 f 和 g 分别表示以当前位置…...

009 | 上证50ETF基金数据分析及预测

项目背景 中国股市的发展历程坎坷,从最初的茫然到现在的逐步成熟,股市已经成为中国经济发展的重要标志之一。然而,当前中国股市仍存在投机行为过度和定价机制不完善等问题。为更好地理解和预测股市走势,本项目聚焦于上证50ETF基金的历史数据分析和未来走势预测。 项目目标…...

Wakanda: 1靶场复现【附代码】(权限提升)

靶机下载地址&#xff1a; wakanda: 1 ~ VulnHubwakanda: 1, made by xMagass. Download & walkthrough links are available.https://www.vulnhub.com/entry/wakanda-1,251/#download 1. 主机发现端口扫描目录扫描敏感信息获取 1.1. 主机发现 nmap -sn 192.168.7.0/24…...

内核函数调试

要进入 bind 函数的内部进行调试&#xff0c;实际上是不能直接在用户空间代码中进入内核内部的 bind 实现&#xff0c;因为 bind 是一个系统调用&#xff0c;它由内核处理。尽管如此&#xff0c;你可以通过以下几种方法来间接调试 bind 函数并理解它的行为&#xff1a; 1. 使用…...

Spring IOC使用DButil实现对数据库的操作

一、DButil、lombok、junit的简单介绍 1.dbutil dbutil是由阿帕奇提供操作数据库的插件&#xff0c;其核心类为QueryRunner&#xff0c;存在方法 .query() 查询&#xff0c;.update() 增删改&#xff1b; <!-- dbutil --> <dependency><groupId>commons-d…...

Android14音频进阶调试之命令播放mp3/aac非裸流音频(八十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更…...

vue中怎么自定义组件

目录 一&#xff1a;功能描述 二&#xff1a;实现过程 一&#xff1a;功能描述 在开发过程中我们经常需要自定义组件完成特定的功能&#xff0c;比如用户详情页&#xff0c;我增加一个调整余额的按钮&#xff0c;点击以后需要打开一个调整余额对话框&#xff0c;输入调整的金…...

BM1反转链表[栈+头插法]

题目要求如下: 问题比较简单,就是将链表中的值进行反转即可。 一种比较简单的方式是使用栈链表的方式来实现,下面是相应的代码: #include <stdio.h> #include <stdlib.h> int arr[10001] {0}; struct ListNode* ReverseList(struct ListNode* head ) {if (head …...

VisionPro二次开发学习笔记10-使用 PMAlign和Fixture固定Blob工具检测孔

使用 PMAlign和Fixture固定Blob工具检测孔 这个示例演示了如何使用 PMAlign 工具和 Fixture 工具来夹持一个 Blob 工具。示例代码将检测支架右上角孔的存在。当点击运行按钮时&#xff0c;将读取新图像。PMAlign 工具运行并生成一个 POSE 作为输出。POSE 是一个六自由度的变换…...

学单片机怎么在3-5个月内找到工作?

每个初学者&#xff0c;都如履薄冰&#xff0c;10几年前&#xff0c;我自学单片机时&#xff0c;也一样。 想通过学习&#xff0c;找一份体面点的工作&#xff0c;又害怕辛辛苦苦学出来&#xff0c;找不到工作。 好在&#xff0c;当初执行力&#xff0c;还算可以&#xff0c;自…...

探索设计模式:观察者模式

探索设计模式&#xff1a;观察者模式 &#x1f9d0;观察者模式简介:gem:核心概念:rainbow:观察者模式的优点:truck:实现步骤1. 定义主题接口2. 实现观察者接口3. 具体主题实现4. 具体观察者实现5. 调用 :triangular_flag_on_post:总结 在实际开发过程中&#xff0c;设计模式的作…...

gradio之持续输入,持续输出(流式)

流式输出yield,比如一个输出控件&#xff0c;想要实时显示内容&#xff0c;用return for循环一次就返回去了。而用yield会持续更新往下执行 for i in range(length):time.sleep(8)yield 总共str(length)条语料&#xff0c;已运行str(i1)条 在Gradio中&#xff0c;某些组件&am…...

Git 常用命令指南:从入门到精通

文章目录 前言1. 初始化一个Git仓库2. 克隆远程仓库3. 查看仓库状态4. 添加文件到暂存区5. 提交代码6. 推送到远程仓库7. 拉取远程仓库的更改8. 分支管理9. 查看提交历史10. 回退到某个版本结语 前言 如果你是一位开发者或者对代码感兴趣&#xff0c;那么你一定听说过Git。Git…...

Camera驱动 汇总表【小驰行动派】

在做Camera BringUp的时候&#xff0c;如果有已经点亮过的驱动源码&#xff0c;对我们的帮助将会非常的大&#xff0c;可以大大加快我们点亮进度。 所以我决定整理汇总接触过得Camera驱动信息。如果你刚好有需要&#xff0c;可以加我薇咨询&#xff08;该资料整理比较花时间&a…...

SSRS rdlc报表 九 在.net core中使用RDLC报表

开发环境 vs 2022企业版 SqlServer数据库 Win11 前言 rdlc报表在aspx中集成的很好,很容易实现,并且功能强大,但随着技术的发展,aspx慢慢的被淘汰,现在已经发展到.net8了,aspx基本上很少用,出的新框架基本上也都是前后端分离,没了aspx的控件加持,rdlc这么厉害的报…...

力扣(2024.08.10)

1. 222&#xff1a;完全二叉树的节点个数 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class Solution:def countNodes(…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...