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

[C++] new和delete

  • 使用new时调用构造函数
  • 使用delete时调用析构函数
  1. 构造函数

使用new动态分配内存时,如果分配的是基本类型的内存,则不会调用构造函数。如果分配的是自定义类型的内存,则会调用构造函数进行对象的初始化。

例如:

int* pInt = new int; // 不会调用构造函数
class MyClass {
public:MyClass() {cout << "MyClass constructor is called" << endl;}
};
MyClass* pObj = new MyClass(); // 调用构造函数
  1. 析构函数

使用delete释放内存时,如果内存中存储的是基本类型,或者使用new分配内存时发生了错误,导致没有成功创建对象,则不会调用析构函数;否则会调用析构函数进行资源的释放。

例如:

int* pInt = new int;
// 使用pInt
delete pInt; // 不会调用析构函数class MyClass {
public:MyClass() {cout << "MyClass constructor is called" << endl;}~MyClass() {cout << "MyClass destructor is called" << endl;}
};
MyClass* pObj = new MyClass();
// 使用pObj
delete pObj; // 调用析构函数
pObj = NULL;

需要注意的是,使用new分配的内存必须在不再使用时通过delete操作符进行释放,否则会造成内存泄漏

同时,为了避免悬垂指针的问题,在删除指针之前必须将指针置为nullptr

  • 在C++中,delete只是释放了指针指向的内存空间,但是并没有将指针本身变成nullptr(空指针)。

  • 这也就意味着,如果在delete后不将指针制空,那么这个指针仍然指向之前释放的那块内存空间,访问它将会产生未定义行为(UB)。

因此,在使用delete释放动态分配的内存后,最好将指针置为nullptr,这样能够避免悬垂指针的问题。

例如:

int *pInt = new int;
//使用pInt
delete pInt;
pInt = nullptr; // 将指针置为nullptr

需要注意的是,将指针置为nullptr只是一种好习惯,而非强制要求。如果你后续没有再次使用该指针或者保证没有悬垂指针的风险,那么也可以不进行指针置空操作。

nullptr是C++11引入的关键字。它用于表示空指针常量,可以用于初始化指针或与指针进行比较。

在C++之前的版本中,通常使用NULL或0来表示空指针。然而,这样的表示方式可能会引起一些歧义和问题。为了解决这些问题,并提供更明确和类型安全的空指针表示,C++11引入了nullptr。

使用nullptr可以明确地表示空指针,避免在某些上下文中与整数0混淆。另外,nullptr还可以作为实现函数重载时的重要工具,与其他类型的指针进行区分。

示例用法:

int* pInt = nullptr; // 初始化指针为空
if (pInt == nullptr) {// 执行某些操作
}void foo(int* ptr) {// 实现重载函数
}
void foo(int i) {// 实现重载函数
}foo(nullptr); // 调用第一个foo函数,传递空指针常量

nullptr是C++中的关键字,用于明确表示空指针常量,提高代码的可读性和类型安全性。


要释放通过new申请的数组,需要使用delete[]操作符,而不是简单的delete

示例代码如下:

int* pArray = new int[10]; // 通过new申请一个int类型的数组// 使用pArraydelete[] pArray; // 释放通过new申请的数组内存
pArray = nullptr; // 将指针置为nullptr

需要注意以下几点:

  1. 使用delete[]来释放通过new[]申请的数组内存。
  2. 在释放数组内存之后,将指针置为nullptr是个好习惯,可以避免悬垂指针问题。
  3. 如果使用new[]分配数组时发生了错误,没有成功创建数组对象,那么在释放数组内存时也不要使用delete[],因为没有成功创建的数组对象不需要释放。

总结起来,使用delete[]来释放通过new[]申请的数组内存,并将指针置为nullptr

相关文章:

  • CentOS使用kkFileView实现在线预览word excel pdf等
  • 【数据结构第 6 章 ②】- 用 C 语言实现邻接矩阵
  • 【C语言】一个RDMACM、Verbs API与epoll一起使用的例子
  • LeetCode-739. 每日温度【栈 数组 单调栈】
  • 美食大赛的题解
  • 飞天使-linux操作的一些技巧与知识点2-TCP的三次握手以及四次挥手以及转换状态
  • 鸿蒙(HarmonyOS)应用开发——简易版轮播图
  • 宇视科技视频监控 main-cgi 文件信息泄露漏洞
  • PostgreSql 设置自增字段
  • SQL注入绕过技术
  • GO闭包实现原理(汇编级讲解)
  • Python查找列表中不重复的数字
  • 【ArcGIS微课1000例】0080:ArcGIS将shp转json(geojson)案例教程
  • 网络基础(八):路由器的基本原理及配置
  • Redis系列之简单实现watchDog自动续期机制
  • [deviceone开发]-do_Webview的基本示例
  • Android 控件背景颜色处理
  • HTML5新特性总结
  • HTML-表单
  • JavaScript中的对象个人分享
  • Linux后台研发超实用命令总结
  • maven工程打包jar以及java jar命令的classpath使用
  • MaxCompute访问TableStore(OTS) 数据
  • Node + FFmpeg 实现Canvas动画导出视频
  • Otto开发初探——微服务依赖管理新利器
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Vue 2.3、2.4 知识点小结
  • Vue.js-Day01
  • 不上全站https的网站你们就等着被恶心死吧
  • 类orAPI - 收藏集 - 掘金
  • 七牛云假注销小指南
  • 前言-如何学习区块链
  • 删除表内多余的重复数据
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • 进程与线程(三)——进程/线程间通信
  • ​低代码平台的核心价值与优势
  • # 透过事物看本质的能力怎么培养?
  • ###C语言程序设计-----C语言学习(3)#
  • #define用法
  • #HarmonyOS:基础语法
  • (14)Hive调优——合并小文件
  • (第61天)多租户架构(CDB/PDB)
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)ObjectiveC 深浅拷贝学习
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • ./configure、make、make install 命令
  • .axf 转化 .bin文件 的方法
  • .NET Core 版本不支持的问题
  • .NET HttpWebRequest、WebClient、HttpClient
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .NET 反射 Reflect
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径