浅谈C/C++的new和delete以及对象池的实现

今天我们来谈谈C++中的new和delete😊😊😊。在软件开发中,常常需要动态地分配和撤销内存空间,C语言中利用库函数malloc和free分配和撤销内存空间的。而在C++中则是 new和delete

  • malloc函数时必须指定需要开辟的内存空间的大小,需要做类型强转
  • malloc开辟内存失败,返回nullptr
  • new 不仅可以做内存开辟(调用构造函数,如果有的话),还可以做内存初始化操作
  • new 开辟内存失败会抛出bad_alloc类型的异常
  • delete 调用析构函数(如果有的话),再调用operator delete,进行free

# malloc、new的使用格式

int *p = (int*)malloc(sizeof(int));  //malloc
if(p == nullptr) return -1;
free(p);int *p1 = new int(20);  //new
delete p1;int *p2 = new int[20](); 
delete[] p2;

# 对于new的使用,有多种方式如下:

int *p = new int(20);  //普通
int *p2 = new (nothrow) int;   //不跑异常
const int *p3 = new const int(40); //常量int data = 2;
int *p4 = new (&data) int(40); //定位new,把指定位置的内存空间对于存储的数据修改

# new 、 delete的底层原理
在new和delete的底层汇编指令上,执行命令时实际上是调用 operator new 和 operator delete 这两个重载函数

在这里插入图片描述
# 重写一遍new / []和 delete / []

void* operator new (size_t size) 
{void* p = malloc(size); //底层还是通过malloc来开辟内存if (p == nullptr) {throw bad_alloc();}cout << "operator new addr: " << p << endl;return p;
}void operator delete(void* ptr)
{cout << "operator delete addr: " << ptr << endl;free(ptr);
}void* operator new[] (size_t size)
{void* p = malloc(size); //底层还是通过malloc来开辟内存if (p == nullptr) {throw bad_alloc();}cout << "operator new[] addr: " << p << endl;return p;
}void operator delete[] (void* ptr)
{cout << "operator delete[] addr: " << ptr << endl;free(ptr);
}int main()
{try{int* p = new int(20);delete p;int* q = new int[10];delete[] q;}catch (const bad_alloc& err) { cerr << err.what() << endl; }return 0;
}

new 和 delete能够混用吗?这里给出一段代码

class Test
{
public:Test(int data = 10){ cout << "Test()" << endl; }~Test() {cout << "~Test()" << endl; }
private:int* ptr;
};int main()
{int* p = new int(20);delete[] p;int* q = new int[10];delete q;Test* pp = new Test();//delete []pp;   //混用delete 和 delete[]delete pp;Test* qq = new Test[5];delete[] qq;//delete qq;  //混用delete 和 delete[]return 0;
}

在这里插入图片描述
我们发现这里对于普通的编译器内置类型,new和delete混用没问题,但是对于对象Test,构造了5次,析构了一次,最后系统崩溃了,why ? ? ? 对于new Test[5]开辟的不只是5个对象的字节,实际上它多开了4个字节用于存储对象的个数,当我们执行delete调用operator delete(void* ptr)时,传入的ptr其实应该是给第一个对象分配内存的地址 - 4,同理对于delete [] pp也会往前找4个字节,而它并不是从它前4个字节的内存上开辟的,会出现问题,即new 和 delete 不能混用
在这里插入图片描述

简单对象池的实现

#include<iostream>
#include<cstring>
using namespace std;template<typename T>
class Queue
{
public:Queue(){_front = _rear = new QueueItem();}~Queue(){QueueItem* cur = _front;while (cur != nullptr){_front = _front->_next;delete cur;cur = _front;}}void push(const T& val){QueueItem* item = new QueueItem(val);_rear->_next = item;_rear = item;}void pop(){if (empty()){return;}QueueItem* first = _front->_next;_front->_next = first->_next;if (_front->_next == nullptr) _rear = _front;delete first;}T front() const { return _front->_next->_data; }bool empty() const { return _front == _rear; }private:struct QueueItem{QueueItem(T data = T()) :_data(data), _next(nullptr) {}// Memory managementvoid* operator new(size_t size){if (_itemPool == nullptr){_itemPool = (QueueItem*)new (std::nothrow) char[Pool_ITEM_SIZE * sizeof(QueueItem)];QueueItem* p = _itemPool;for (; p < _itemPool + Pool_ITEM_SIZE - 1; p++){p->_next = p + 1;}p->_next = nullptr;}QueueItem* p = _itemPool;_itemPool = _itemPool->_next;return p;}void operator delete(void* ptr){QueueItem* p = static_cast<QueueItem*>(ptr);p->_next = _itemPool;_itemPool = p;}T _data;QueueItem* _next;static const int Pool_ITEM_SIZE = 1000000;static QueueItem* _itemPool;};QueueItem* _front; // HeadQueueItem* _rear;  // Tail
};template<typename T>
typename Queue<T>::QueueItem* Queue<T>::QueueItem::_itemPool = nullptr;int main()
{Queue<int> q;for (int i = 0; i < 1000000; i++) {q.push(i);q.pop();}cout << q.empty() << endl;return 0;
}

🌻🌻🌻以上就是浅谈C/C++的new和delete以及对象池的实现的内容,如果聪明的你浏览到这篇文章并觉得文章内容对你有帮助,请不吝动动手指,给博主一个小小的赞和收藏 🌻🌻🌻

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法笔记之蓝桥杯pat系统备考(2)

算法笔记之蓝桥杯&pat系统备考&#xff08;1&#xff09; 文章目录 五、数学问题5.2最大公约数和最小公倍数5.2.1最大公约数5.2.2最小公倍数 5.3分数的四则运算5.3.1分数的表示与化简5.3.2分数的四则运算5.3.3分数的输出 5.4素数&#xff08;质数&#xff09;5.4.1[素数的…

如何在Linux使用docker部署Swagger Editor并实现无公网IP远程协同编辑API文档

目录 前言 Swagger Editor本地接口文档公网远程访问 1. 部署Swagger Editor 2. Linux安装Cpolar 3. 配置Swagger Editor公网地址 4. 远程访问Swagger Editor 5. 固定Swagger Editor公网地址 结语 前言 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 …

什么是Git引用和分支?

一. 引言 什么是Git引用和分支&#xff1f;比如我在 Github 上一个项目的 .git/refs目录下&#xff1a; ├─heads │ dev │ master │ ├─remotes │ └─origin │ master │ └─tags refs 目录下包含了 heads、remote、tags 三个子目录&#xff0…

彩虹外链网盘界面UI美化版超级简洁好看

彩虹外链网盘界面UI美化版 彩虹外链网盘&#xff0c;是一款PHP网盘与外链分享程序&#xff0c;支持所有格式文件的上传&#xff0c;可以生成文件外链、图片外链、音乐视频外链&#xff0c;生成外链同时自动生成相应的UBB代码和HTML代码&#xff0c;还可支持文本、图片、音乐、…

【解读】区块链和分布式记账技术标准体系建设指南

大家好&#xff0c;这里是苏泽。一个从业Java后端的区块链技术爱好者。 今天带大家来解读这份三部门印发的行业建设指南《区块链和分布式记账技术标准体系建设指南》 原文件可查看P020240112840724196854.pdf (www.gov.cn) 以下是个人解读&#xff0c;如有纰漏请指正&#xff…

Editor.md-编辑器

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

【Canvas与艺术】绘制简单线条时钟

【效果】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>65.绘制简单时钟</title><style type"text/css"&…

CVE-2023-49442 利用分析

1. 漏洞介绍 ​ JEECG(J2EE Code Generation) 是开源的代码生成平台&#xff0c;目前官方已停止维护。JEECG 4.0及之前版本中&#xff0c;由于/api接口鉴权时未过滤路径遍历&#xff0c;攻击者可构造包含 ../ 的url绕过鉴权。攻击者可构造恶意请求利用 jeecgFormDemoControlle…

用连续自然数之和来表达整数 - 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 一个整数可以由连续的自然数之和来表示。给定一个整数&#xff0c;计算该整数有几种连续自然数之和的表达式&#xff0c;且打印出每种表达式。 输入描述 一个目…

翻转时钟效果

时分秒三个部分结构功能完全一致&#xff0c;均有四块构成&#xff0c;上下各两块。 正面可见&#xff0c;背面不可见&#xff0c;同时需要调整翻转过程中的z-index。 初始状态card2为已经翻转状态。 calendar.html <!DOCTYPE html> <html lang"en">&…

【算法】一类支持向量机OC-SVM(1)

【算法】一类支持向量机OC-SVM 前言一类支持向量机OC-SVM 概念介绍示例编写数据集创建实现一类支持向量机OC-SVM完整的示例输出 前言 由于之前毕设期间主要的工具就是支持向量机&#xff0c;从基础的回归和分类到后来的优化&#xff0c;在接触到支持向量机还有一类支持向量机的…

幸福金龄会携手广东文艺团队共谱文化新篇章《锦绣中华》第二届中老年文旅展演盛大开幕

近日&#xff0c;幸福金龄会携手广东省各支文艺团队及艺术家&#xff0c;开启了《锦绣中华》第二届中老年文旅游活动。此次活动得到了各大媒体对于老年旅游服务的深度关注&#xff0c;并获得了各地文旅企业的热情配合&#xff0c;共同为中老年朋友们打造了一场文化盛宴。 近期&…