关于C++的placement new和placement delete

C++ Placement Delete:与 Placement New 对应的销毁操作 是 C++ 中一个重要的异常处理机制,它与配合使用,可以在构造函数抛出异常时,清理已经分配的资源,防止内存泄漏。虽然它不是每天都会用到的特性,但在某些特定的场景下,它可以发挥巨大的作用。希望今天的讲座能帮助大家更好地理解的概念和用法。记住,理解内存管理是成为一名优秀的 C++ 程序员的关键。如果我在构造对象时,使用了自定义的内存池,那么应该如何实现?欢迎大家在评论区留言讨论! 阅读详情

昨天发贴提了个问题,今天总结在这。原帖点击进入,有兴趣可以看看,我呆会儿还会说。

C++的new是语言自定义的操作符,这个操作符的行为包含两件事,而且你不能改变。

第一件事:调用operator new分配内存。所以通常说的重载new函数其实重载的是operator new,你无法重载new。

第二件事:调用你要new的对象的所属类的构造函数初始化第一步中分配的内存。这就是为什么你Object *pobj = new Object后,可以直接使用pobj->调用类中函数的原因。

delete操作符也是类似,不过先调用析构函数,然后释放内存,对应有一个operator delete。


帖子中的代码的目的是重载operator new和operator delete,把new和delete的历史通过一个ostream记录下来。好了,上代码了:

#include <iostream>

using namespace std;

class B{
public:
  B(){cout << "ctor B" << endl;}
  ~B(){cout << "dtor B" << endl;}
  void * operator new(size_t size, ostream& out){
    out << "new B" << endl;
    return ::operator new(size);
  }
  void operator delete(void *mem, ostream& out){
    out << "delete B" << endl;
    ::operator delete(mem);
  }
};

int main(){
  B *pb = new (cout)B;
  B *pb2 = ::new B;
  //delete pb;   这句编译不通过,说no suitable ‘operator delete’ for ‘B’
  ::delete pb2;
}

如果注释那段没问题,这段代码(期望)的输出是:

new B
ctor B
ctor B
dtor B
delete B
dtor B

class B就不解释了,直接看main函数:

  B *pb = new (cout)B; 这句new一个B的对象,因为B类中重载了operator new,所以需要传递一个ostream的对象进去,就像这样传递。如果你这样调用:  B *pb = new B;那是会报错的,因为B类中的operator new把默认的隐藏掉了。这句产生输出:new B ctorB。

  B *pb2 = ::new B; 这句也是new一个B的对象,但是new前面多了两个冒号,意思是调用全局的new,调用了上面说的被隐藏调的operator new。这句产生输出:ctor B。

  delete pb; 这句想要delete掉pb指向的对象,但是失败,原因在后面。这句(期望)输出:dtor B delete B。

  ::delete pb2; 这句delete掉pb2指向的对象,调用全局的delete,没有问题,这句输出:dtor B。


关于delete pb为什么失败:

2楼 RabbitLBJ:

先说声楼主最好还是把new,delete声明称static好些

把出错的行改成如下
B::operator delete(pb,cout);
即可调用到placement delete了,但是想法和楼主的有差距,这函数里面直接释放内存,就不会再析构了
貌似这个delete是不能通过delete关键字在外面调用的,这个一般都是给系统在placement new出错时调用
而且只要有使用placement new,析构一般都是要手动进行的

4楼 pengzhixi:

c++为什么没有内置的"placement new"是因为 没办法提供一个通用的。
B *pb = new (cout)B;当我们写出这样的代码的时候,c++不能推出pb指针里面存放的对象类型。(虽然我们知道是什么类型)。所以不会有placement delete.只有在placement new抛出异常的时候,编译器才会调用placement delete.这个时候因为构造不成功所以只需要负责释放内存即可。所以LZ只能是先显示调用析构函数,然后在显示调用placement delete.

另外:不要重载operator new operator delete这些东西。

这两位朋友解释的很清楚了,我就不画蛇添足了,在此感谢这两位朋友的解答。



Reference:

Scott Meyers. Effective C++ 3rd edition. 2005

Scott Meyers. More Effective C++ . 1996

UE4逆向实战:如何快速定位UWorld和GName的5种实用技巧(含版本差异分析) 本文详细介绍了UE4逆向工程中快速定位UWorld和GName的5种实用技巧,包括特征码定位法、动态行为分析法、静态符号分析法等,并针对不同版本差异提供了适配方案。特别强调了UWorld作为游戏世界核心容器和GName作为名称管理系统的重要性,帮助开发者高效进行游戏逆向分析。 阅读详情

相关推荐

保姆级教程:用Fiddler+夜神模拟器搞定抖音App抓包(附SSL Pinning绕过实战)

本文提供了一套完整的移动端抓包解决方案,详细介绍了如何使用Fiddler和夜神模拟器进行抖音App抓包,并重点讲解了SSL Pinning绕过技术。通过Xposed框架和JustTrustMe模块的组合,实现高效抓包,适用于产品分析、竞品研究和安全测试等场景。

weixin_30855099的博客 422

c++ placement new操作符的使用技巧

在c++中new和delete操作是我们操作内存最常用的一对操作符,在使用new时编译器会申请内存,然后调用类的构造函数来初始化对象,调用delete会销毁对象同时释放该对象占用的内存,并且我们可以重载new操作符。 还有一个不常用的new操作placement new,在使用时需要我们传入一个指针,此时会在该指针指向的内存空间构造该对象,该指针指向的地址可以使堆空间,栈空间,也可以是静态存储区

D_Guco的专栏 7772

基于opencv-ANN的水果识别模型训练

本文通过opencv-ann-mlp训练模型,实现对五种水果进行分类识别。本文详细介绍该项目的各个过程,包括数据准备、预处理、样本读取、训练数据集制作、训练标签制作、模型参数设置、模型训练,模型测试验证等,总结该过程需要注意的事项。

qq_15985873的博客 3973

placement new和placement delete(重载new和delete2)

placement new和placement delete参考:《Effective C++》placement new和placement delete 1 什么是placement new和placement delete 2 如何使用placement版本的new和delete 3 从内存泄露出发 a 什么时候new一个对象会发生内存泄露 b 当placement new和placement

Sei的博客 1482

从零上手:基于英飞凌TC377的UDE STK 5.0实战调试指南

本文详细介绍了基于英飞凌TC377芯片和UDE STK 5.0的实战调试指南,涵盖硬件连接、工作空间配置、程序烧录、多核调试等关键步骤。特别针对汽车电子领域常见的多核架构调试难题,提供了断点设置、变量监控等实用技巧,帮助开发者快速上手并优化调试效率。

weixin_30839881的博客 683

为什么你的XGBoost多分类效果不如预期?可能是这5个参数没调对

本文深度剖析了XGBoost模型在处理多分类问题时效果不佳的五大关键参数陷阱。针对多分类问题的独特性,文章提供了max_depth、learning_rate、采样参数及正则化参数等核心参数的量化调整策略与诊断方法,帮助开发者精准调优,有效提升模型在各类别上的均衡性能与泛化能力。

weixin_29182481的博客 296

C++ 的placement new和placement delete

参考: placement new和placement delete_hujing_Liu-优快云博客 《effctive C++》p256 通常的C++程序中,new和delete表达式总是成对出现,并且分别调用了全局的operator new和operator delete,这两个全局操作符(或者直接理解为全局的函数)的基本形式如下: void * operator new ( std::size_t) throw ( std::bad_alloc ); void operator delete (

zj 1852

ROS & ROS2 机器人深度相机激光雷达多传感器标定工具箱入门教程(一)

multisensor_calibration 是一个积极维护的通用标定工具箱,用于辅助基于目标的多传感器标定,支持 ROS 1 和 ROS 2。它提供了多种方法和应用来标定复杂的多传感器系统,例如。

2506_90492529的博客 3261

C++——new,delete,与placement new。

介绍new和delete原理、用法、常见错误、介绍定位new

chfens的博客 755

【Charge】仿真目录

Author: JiJi\textrm{Author: JiJi}Author: JiJi Created Time: 2026.01.20\textrm{Created Time: 2026.01.20}Created Time: 2026.01.20 Modified Time: 2026.01.20\textrm{Modified Time: 2026.01.20}Modified Time: 2026.01.20工作流程材料模型[Charge] 电荷分布与折射率变化理论 [Charge] FDTD

u011699626的博客 314

【Arduino 动手做】六舵机自平衡 Rotary Stewart 平台

《Arduino六舵机自平衡Rotary Stewart平台项目》 该项目展示了一个基于Arduino的六自由度Rotary Stewart平台,通过六个舵机实现动态平衡控制。设计采用激光切割框架和TAMIYA 70171套件,提供详细组装指南和开源固件(GitHub可获取)。开发者丹·罗耶分享了3D打印文件、视频演示及运动学优化需求,强调该平台可扩展应用于游戏控制(如Kerbal Space Program)或教育领域。项目链接包含完整资源包,鼓励用户参与改进并分享创作成果。该案例体现了Arduino在机

雕爷学编程 1090

placement new和placement delete

在第五版的《C++ primer》中,定位new

hujing_Liu 1619

OpenClaw + Antigravity + 飞书完整部署教程

在 Linux 服务器上部署 OpenClaw,使用 Antigravity 本地代理 AI 模型,并接入飞书实现 24 小时在线 AI 助手。

Maynor的博客 1788

Effective C++条款52:定制new和delete之(写了placement new也要写placement delete)

placement new和placement delete在C++中可能并不常用,但是你需要了解它们 关于placement new语法可以参阅:https://blog.youkuaiyun.com/qq_41453285/article/details/104690501 一、正常签名式的new和delete 对于使用new来创建对象时,其可能在两个地方会抛出异常: ①当在调用new()时,ne...

董哥的黑板报 938

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Effective C++条款52:定制new和delete——写了placement new也要写placement delete

placement new和placement delete在C++中可能并不常用,但是你需要了解它们 关于placement new语法可以参阅:https://blog.youkuaiyun.com/qq_41453285/article/details/104690501 一、正常签名式的new和delete 对于使用new来创建对象时,其可能在两个地方会抛出异常: ①当在调用new()时,new()函数中可能会抛出异常 ②如果new()函数没有抛出异常,但是后面对象的构造函数可能会抛出异常 当

www_dong的博客 267

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

深度剖析C++的new、delete和placement new

如果申请的是内置类型的空间,new和mallocdelete和freenew/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。调用函数申请空间在申请的空间上执行构造函数,完成对象的构造什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

qq_74013365的博客 2060

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C++ 的 new 和 delete : new operator, operator new, placement new, delete operator, operator delete

C++ 的 new 和 delete :new operator, operator new, placement new, delete operator, operator delete 1. new operator new operator 完成了两件事情:用于申请内存和初始化对象。 例如: string* ps = new string("abc"); 2.operator n

iw1210的专栏 555

C++中new和delete的多重面孔:operator new、new operator与placement new解析

本文深入解析C++中new和delete的多层含义,重点区分了new operator(分配内存+构造对象)、operator new(仅内存分配)和placement new(指定地址构造)三种概念。同时介绍了对应的delete操作,并强调数组处理时new[]/delete[]的配对使用。文章通过示例代码展示了不同场景下的正确用法,最后总结各概念的特性与定制方法,为复杂内存管理(如内存池、对象池)提供了实践指导。理解这些底层机制有助于开发者更精准地控制对象生命周期和内存分配。

极客BIM工作室 892

C++中placement new和delete讨论

在程序设计中频繁地进行动态内存分配和释放容易造成内存碎片,给需要长期稳定运行的系统带来了隐患。尽管现代操作系统在内存管理的稳健性上已经有了较大提高,但是动态内存分配的效率、稳定性等问题仍然是一个困扰。

华清远见 | 程序员的学习天堂 684

170-C++基础(new和delete基础,placement new定位new)

new和delete new和malloc的区别是什么? delete和free的区别是什么? malloc和free,称作C语言的库函数; malloc只管开辟内存(按字节开辟),不管初始化。 new和delete,称作运算符。 new后边直接指定类型,如int,在堆上开辟int类型的内存。 new和delete,称作运算符。 new后边直接指定类型,如int,在堆上开辟int类型的内存。 malloc开辟内存失败,是通过返回值和nullptr空指针做比较; 而new开辟内存失败,是通过抛出b

Edward_LF的博客 373

C++ new 和 delete 的讲解

概述 运算符 new 和 delete 看起来很简单,但是它们也有不少的知识点。对于new来说就有 new operator、operator new、placement new 和 new operator[]等。对于 delete 也有 delete operator、poerator delete、delete operator[] 等。下面就进行按个整理。 1、new operator 平...

weixin_39640298的博客 5065

《Effective C++》学习笔记(条款52:写了placement new 也要写 placement delete)

最近开始看《Effective C++》,为了方便以后回顾,特意做了笔记。若本人对书中的知识点理解有误的话,望请指正!!! placement new 和 placement delete 在C++中并不常见,如果你不熟悉它们,也不用担心。当你写一个 new 表达式时: Widget* pw = new Widget; 共有两个函数被调用:一个是以分配内存的 operator new,一个是 Widget 的默认构造函数。 假如第一个函数调用成功,但第二个函数却抛出异常,这时需要释放第一步分配得到的内存,

ZLX的博客 1329

【Effective C++】读书笔记 条款52:写了placement new 也要写placement delete

定制new 和 delete 条款52:写了placement new 也要写placement delete1. new

夏至亦韵 686

new、placement new、delete、placement delete

new表达式 c++提供了new关键字和delete关键字,分别用于申请和释放内存空间,其中new表达式的语法如下: new new-type-id (optional-initializer-expression-list) new表达式做两件事情: 在堆(heap)上申请一块空间,大小等于sizeof(new-type-id) 在申请的空间上构建对象,即调用对象的构造函数 new...

finewind的专栏 917
上一篇: qt下的跨目录多工程编译
下一篇: Lisp the language
High_High
博客等级 码龄19年 131粉丝 34原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值