【C++】动态内存管理new和delete
文章目录
- 一、C++的内存管理方式
- 二、new和delete的用法
- 1.操作内置类型
- 2.操作自定义内置类型
- 三、new和delete的底层实现
- 1.operator new和operator delete函数
- 2.new和delete的实现原理
- 四、定位new表达式
- 五、malloc/free和new/delete的区别
一、C++的内存管理方式
之前在C语言的动态内存管理我们学过,用来动态开辟空间的malloc/calloc/realloc和释放空间的free。C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++将malloc和free封装起来并起了新的名字new和delete。
二、new和delete的用法
1.操作内置类型
new和delete是操作符,不是函数,不需要单独添加头文件。
动态申请一个int类型的空间
int* p1 = (int*)malloc(sizeof(int));
int* p2 = new int;
//释放内存
free(p1);
delete p2;
动态申请一个int类型的空间并初始化
int* p3 = (int*)malloc(sizeof(int));
*p3 = 1;
int* p4 = new int(1);
//释放内存
free(p3);
delete p4;
动态申请10个int类型的空间
int* p5 = (int*)malloc(sizeof(int) * 10);
int* p6 = new int[10];
//释放内存
free(p5);
delete[] p6;
动态申请10个int类型的空间并初始化(C++11)
int* p7 = (int*)malloc(sizeof(int) * 10);
int* p8 = new int[10]{ 1,2,3 };//后面未初始化的部分默认为0
//释放内存
free(p7);
delete[] p8;
注意:申请和释放单个元素的空间,使用new/delete操作符;申请和释放连续的空间,使用new[ ]和delete[ ],一定要配套使用!
通过对比,明显new和delete的使用更方便简洁;可以发现malloc与new的几个区别:
1.malloc和free是函数,而new和delete是操作符;
2.并且malloc申请空间时不会初始化,而new可以初始化,只需要在()(单个空间)或者{}(多个连续空间,C++11才引入)里赋值即可;
3.malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,如果是多个对象,[ ]中指定对象个数。
4.malloc的返回值为void*,在使用时必须强转,new不需要,因为new后跟的是空间的类型
但是,这些优点并不足以解释C++不继续使用C语言的malloc和free,去创建一个新用法。new和delete最大的价值体现自定义类型的操作上。
2.操作自定义内置类型
对于内置类型,malloc/free与new/delete区别不大,真正的区别在于自定义类型。
malloc/free与new/delete最大的区别是:申请自定义类型对象时,malloc是纯粹的开辟空间,不会初始化;而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理。
对于需要资源申请的自定义类型更能体现其优势,以链表为例
new会先开辟空间再调用构造函数初始化,delete会先调用析构函数清理资源再释放空间,这点是与malloc/free的最大区别,也是C++新增用法的主要原因。
三、new和delete的底层实现
1.operator new和operator delete函数
new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,也是对malloc和free进行过封装的函数。
operator new和malloc的最大区别就是当申请错误时,处理的方式不一样。
malloc申请空间失败时会返回NULL
operator new函数实际通过malloc来申请空间,申请空间成功时直接返回,失败则抛异常
new和delete是对operator new和operator delete这两个全局函数进行的封装。所以new/delete与malloc/free的不同:malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要判空,申请失败会抛异常。
2.new和delete的实现原理
new在底层调用operator new全局函数来申请空间,delete在底层调用operator delete全局函数来释放空间。
通过反汇编可以看到,new先调用operator new(本质上是通过malloc)来申请空间,然后再调用构造函数进行初始化;delete先调用析构函数完成资源的清理,再调用operator delete释放空间。
对于内置类型
new和malloc,delete和free基本类似,不同的是:new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。
对于自定义类型
new原理:先调用operator new来申请空间,然后再调用构造函数进行初始化;
delete原理:先调用析构函数完成资源的清理,再调用operator delete释放空间。

四、定位new表达式
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
格式:
new(指针名)类型或者new(指针名)类型(参数值)
对于自定义类型的对象,需要使用new的定义表达式进行显示调用构造函数和析构函数进行初始化和资源清理。
class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}
private:int _a;
};
int main()
{// p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行A* pa = (A*)malloc(sizeof(A));new(pa)A;//显示调用构造函数//new(pa)A(10);pa->~A();//显示调用析构函数free(pa);return 0;
}
为什么要显示调用构造和析构?
因为pa是是指针类型,属于内置类型,不会自动调用构造和析构,所以需要显示调用。
定位new表达式在实际中一般是配合内存池使用。 内存池的工作原理是先向系统一次性申请比较大的空间,没有初始化,当我们每次去申请空间时就直接使用内存池里的空间,然后再进行初始化。
五、malloc/free和new/delete的区别
1.malloc和free是函数,new和delete是操作符;
2.malloc申请的空间不会初始化,new可以初始化;
3.malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可, 如果是多个对象,[ ]中指定对象个数即可;
4.malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型;
5.malloc申请空间失败时返回NULL,因此使用时必须判空,new不需要判空,申请失败会抛异常;
6.申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理。
相关文章:
【C++】动态内存管理new和delete
文章目录 一、C的内存管理方式二、new和delete的用法1.操作内置类型2.操作自定义内置类型 三、new和delete的底层实现1.operator new和operator delete函数2.new和delete的实现原理 四、定位new表达式五、malloc/free和new/delete的区别 一、C的内存管理方式 之前在C语言的动态…...
Java面向对象特性
Java继承: 继承的概念: 在Java中,继承(inheritance)是面向对象编程的一个重要概念,它允许一个类(子类)继承另一个类(父类)的属性和方法。通过继承,…...
odoo17 tree视图添加按钮
需求描述 点击下图中tree视图上的同步退货单按钮,弹出相应的form视图进行退货单同步,然后点击同步按钮调用后端python代码处理。 实现步骤 主要文件目录结构 js文件的创建 /** @odoo-module **/ import {registry } from "@web/core/registry"; import {listVie…...
PreparedStatement 与Statement 的区别,以及为什么推荐使用 PreparedStatement ?
在Java中,PreparedStatement和Statement都是用于执行SQL语句的重要接口,但它们在功能、安全性和性能上有着显著的差异。理解这些差异对于编写高效且安全的数据库应用程序至关重要。 Statement:基本的SQL执行者 首先,让我们从Sta…...
wsl ubuntu 安装Anaconda3步骤
如何在Ubuntu上安装Anaconda3呢?本章记录整个安装过程。 1、下载脚本 https://mirrors.bfsu.edu.cn/anaconda/archive/Anaconda3-2023.09-0-Linux-x86_64.sh 下载之后,将脚本上传到Ubuntu里。 2、安装脚本 bash Anaconda3-2021.11-Linux-x86_64.sh根据提示进行安装,提示输…...
Vue3响应式 ref全家桶
<template><div>{{ man.name }}<hr><button click"change">修改</button></div> </template> <script setup lang"ts"> const man {name:"cc"} const change () >{man.name "大cc&q…...
Mac(M1芯片)安装多个jdk,Mac卸载jdk
1.jdk下载 oracle官方链接:oracle官方下载链接 2.安装 直接下一步,下一步就行 3.查看是否安装成功 出现下图内容表示安装成功。 4.配置环境变量 open -e .bash_profile 路径建议复制过去 #刷新环境变量 source ~/.bash_profile 5.切换方法 6.jdk…...
Warning message:package ‘ggplot2’ is not available (for R version 3.2.3)
install.packages(ggplot2) Installing package into ‘/usr/local/lib/R/site-library’ (as ‘lib’ is unspecified) Warning message: package ‘ggplot2’ is not available (for R version 3.2.3) 根据你提供的信息,警告消息表明在你的R版本(3.2.3…...
Spring Boot 过滤器和拦截器详解
目录 Spring Boot 过滤器1.什么是过滤器2.工作机制3.实现过滤器 Spring Boot 拦截器1. 什么是拦截器2. 工作原理3.实现4.拓展(MethodInterceptor 拦截器)实现 过滤器和拦截器区别过滤器和拦截器应用场景过滤器拦截器 Spring Boot 过滤器 1.什么是过滤器 …...
Eureka介绍与使用
Eureka是一个开源的服务发现框架,由Netflix开发并在2015年成为Apache的顶级项目。Eureka的核心功能是服务注册与发现,它允许微服务应用在启动时将自己注册到Eureka服务器,并能通过Eureka服务器来发现其他已注册的服务。 使用Eureka有以下几个…...
JVM专题九:JVM分代知识点梳理
今天开始,咱们开始剖析JVM内存划分的原理细节,以及我们创建的那些对象在JVM中到底是如何分配,如何流动的,首先解决第一个问题:JVM内存的一个分代模型:年轻代、老年代、永久通过之前的专题我们知道,那就是我…...
wireshark常用过滤命令
wireshark常用过滤命令 wireshark抓包介绍单机单点:单机多点:双机并行: wireshark界面认识默认布局调整布局(常用)显示FCS错误 wireshark常见列Time回包数据报对应网络模型 wireshark基本操作结束抓包再次开始抓包 **wireshark常用过滤命令**…...
「全新升级,性能更强大——ONLYOFFICE 桌面编辑器 8.1 深度评测」
文章目录 一、背景二、界面设计与用户体验三、主要新功能亮点3.1 高效协作处理3.2 共同编辑,毫无压力3.3 批注与提及3.4 追踪更改3.5 比较与合并3.6 管理版本历史 四、性能表现4.1 集成 AI 工具4.2 插件强化 五、用户反馈与使用案例 一、背景 Ascensio System SIA -…...
线程版服务器实现(pthread_server)
用到的所有方法所需要的参数可以在wrap.c文件中查询,wrap中找不到的直接通过man手册查询 1.首先介绍一下我自己写的包裹文件,里面有各种在可能要用到的方法 wrap.c: #include <stdlib.h> #include <stdio.h> #include <unistd.h> #…...
js异常处理方案
文章目录 异常处理方案同步代码的异常处理Promise 的异常处理async await 的异常处理 感谢阅读,觉得有帮助可以点点关注点点赞,谢谢! 异常处理方案 在JS开发中,处理异常包括两步:先抛出异常,然后捕获异常。…...
C++文件路径处理2 - 路径拼接路径解析
1. 关键词2. filesystem.h3. filepath.cpp6. 测试代码7. 运行结果8. 源码地址 1. 关键词 关键词: C 文件路径处理 路径拼接 获取父目录的路径 获取文件名 获取拓展名 跨平台 应用场景: 路径的拼接路径的解析 2. filesystem.h #pragma once#include…...
数据结构5---矩阵和广义表
一、矩阵的压缩存储 特殊矩阵:矩阵中很多值相同的元素并且它们的分布有一定的规律。 稀疏矩阵:矩阵中有很多零元素。压缩存储的基本思想是: (1)为多个值相同的元素只分配一个存储空间; (2)对零元素不分配存储空间。 1、特殊矩阵的压缩存储 (1)对称矩…...
jquery使用infinitescroll无线滚动+自定义翻页
jquery版本 jquery-1.8.3.js infinitescroll版本 2.0.0 如果infinitescroll版本最新的jquery版本也要用新的 接口用nodejs jquery.infinitescroll.js官网地址 前端代码《接口返回JSON数据》 <!DOCTYPE html> <html lang"en"> <head><meta cha…...
【漏洞复现】锐捷统一上网行为管理与审计系统——远程命令执行漏洞
声明:本文档或演示材料仅供教育和教学目的使用,任何个人或组织使用本文档中的信息进行非法活动,均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 锐捷统一上网行为管理与审计系统naborTable/static_convert.php…...
通义灵码上线 Visual Studio 插件市场啦!
通义灵码,是阿里云出品的一款基于通义大模型的智能编码辅助工具,提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码优化、注释生成、代码解释、研发智能问答、异常报错排查等能力,提供代码智能生成、研发智能问答能力。 通义灵…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...


new会先开辟空间再调用构造函数初始化,delete会先调用析构函数清理资源再释放空间,这点是与malloc/free的最大区别,也是C++新增用法的主要原因。
new和delete是对operator new和operator delete这两个全局函数进行的封装。所以new/delete与malloc/free的不同:malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要判空,申请失败会抛异常。
通过反汇编可以看到,new先调用operator new(本质上是通过malloc)来申请空间,然后再调用构造函数进行初始化;delete先调用析构函数完成资源的清理,再调用operator delete释放空间。