>>> 背景
最近在看一些c++资料的过程中,说到在初始化列表中使用关键字new来分配新内存不是异常安全的,应该使用运算符new。这里就引发了我对c++ new的全新认识。
class a {public: a(int a) : px(new int(a)) {} // 当然这里基础类是不会异常的 int* px;};>>> 内容
首先我们来回忆一下最常规的new用法。首先创建一个测试类a,并在其构造和析构函数里面打印提示语句。可以发现,在new一个a对象的时候调用了构造函数,在delete一个a对象的时候析构了此对象。而且与c标准库中的malloc函数相比,new关键字不需要知道分配的字节数,而是对类型大小做了自动推断,显然更加方便。
class a {public: a(int a) : _a(a) { cout < < object a( < < _a < < ) is constructed.n; } ~a() { cout < < object a( < < _a < < ) is destructed.n; } int _a;};int main() { a* obj = new a(1); delete obj; return 0;}object a(1) is constructed.object a(1) is destructed.但是方便的代价就是隐藏了很多细节,从而可能导致使用者在没有充分理解的情况下造成误用。其实关键字new做了非常多的操作。
这里首先给出3个概念,分别是:关键字new、操作符new和放置new(或者说,keywords new、operator new、placement new)。它们之间的关系大概如下所示。
当我们使用关键字new去创建一个对象时,会首先根据a类型推断出需要申请的内存字节数,然后再交给operator new去按字节数申请一块可用的内存(否则抛出异常),最后调用类的构造函数创造一个对象保存在申请的这段内存中。
而placement new起到的作用是在分配好的内存上创建对象,和operator new有那么一点互补的意思。placement new的引入是为了避免一些频繁的内存申请和回收操作,可以专门申请一块内存做重复的计算,而不是需要一个对象就申请一个内存,从而提高效率。
下面是一个比较综合的例子,来表现这些new之间不同。可以看到,我们首先通过operator new来创建一块能够容纳3个a对象的内存空间,然后通过placement new来在这个申请好的内存空间上创建对象,最后使用operator delete把申请的空间销毁。
可以看到operator new不会调用构造函数,operator delete也不会调用析构函数。通过placement new配合起始指针的偏移,可以逐个在新内存上创建有意义的数据对象。
int main() { a* mempool = (a*)operator new(sizeof(a) * 3); cout < < memory is allocated!n; a* obj1 = new(mempool) a(1); a* obj2 = new(mempool + 1) a(2); a* obj3 = new(mempool + 2) a(3); cout < _a < < endl; cout < _a < < endl; cout < _a < < endl; operator delete(mempool); cout < _a < < endl; cout < _a < < endl; cout < _a < >> 小结
可以看出,c++在内存分配引入了不少的概念,operator new和operator delete都是可以被自定义类重载的,这就给予了程序员很好的自由度。除了使用new和delete来管理内存外,c++还引入了更为复杂的allocator(或分配器)的概念。
HTC U Ultra开售两天销量却惨不忍睹,看来情怀也不是那么好卖
激光雷达让自动驾驶汽车成为现实的技术
一个DCN模型从嵌入和堆积层开始
蓄力向上!Longsys RDIMM企业级内存条迎来重大突破
HTTPS如何保证数据安全?讲得很细!
C++内存管理operator new和placement new
恩智浦与Amazon Web Services (AWS)携手合作,拓展互联汽车商机
iPhone xr到底有没有必要升级系统
基于MODBUS通信协议的低压交流配电柜智能监控系统
5G领先的唯一标志是商业模式领先
WTR096语音播放语音芯片IC:创新应用于电池电量检测与AD按键扩展
选择3D传感器时需要注意什么
在半导体应用领域,玻璃是多功能的通用材料
电脑不启动/反复重启问题
华海清科科创板上市申请 为中芯国际等提供CMP设备
通过电化学和化学方法进行LiFePO4的预锂化
华为发布nova8系列手机,搭载前置Vlog视频双镜头
美信推出DS2482-100单通道1-Wire主控制器
英国易捷航空称电动飞机将推迟可能至2030年投入使用
米家互联网洗烘一体机高清图赏