C++中令人混淆的3个new和delete

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

在深入学习C++的过程中遇到3个new和delete让我十分迷惑,经过学习,有了点初步理解的感觉。总结如下

 

 

C++中,内存分配和对象构造紧密纠缠,就像对象析构和内存回收一样。使用new 表达式的时候,分配内存,并在该内存中构造一个对象,使用delete的时候,调用析构函数撤销对象,并将对象所用内存返还给系统。

 

 

C++提供了一下两种方法来分配和释放未构造的原始内存:

1)allocator类的allocate 和 deallocate成员函数

2)标准库中的 operator new 和 operator delete。

 

C++还提供了在原始未构造的内存中构造和析构对象:

1)allocator类的construct 和 destroy成员函数

2)定位new表达式,接收指向未构造的内存的指针,并在该空间中初始化一个对象或数组。

3)直接调用对象的析构函数撤销对象。

 

 

 

 

 

1. new 表达式 和 delete 表达式

 

    就是我们最常用的。比如:A* a = new A();  delete a; 这中用法很常见。

    但是很少人了解里面的机制。

 

其实,当使用new的时候,发生了3个步骤:

   

   1) 调用 operator new 的标准库函数,分配足够大的原始未类型化的内存。(没有进行构造)

   2) 运行该类型的构造函数

   3) 返回指向新分配并构造的对象指针。

 

delete是发生了2步:调用析构函数,释放内存空间。

 

 

2. operator new 和 operator delete

 

operator new 和 operator delete的设计意图是供表达式new 和 delete 使用。但是他们通常是标准库中可调用的函数。可以使用他们获得 未构造 内存空间。他们有点类似与allocator类的 allocate 和 deallocate成员函数。

 

operator new 和 operator delete有两个重载版本:

 

void *operator new(size_t);

void *operator new[](size_t);

 

void *operator delete(void*);

void *operator delete[](void*);

 

 

他们在void*指针,而不是类型化指针上操作。并且只是分配内存空间,并不初始化。

 

 

3 placement new (翻译成 定位new表达式)

 

定位new表达式在已经分配了的内存中初始化了一个对象。它并不分配内存。相反,它接收指向已经分配的但是没有构造的内存指针,并在该内存中初始化一个对象。 它能使我们在特定的,预分配的内存地址构造一个对象。

 

定位new表达式是:

 

new (place_address) type

new (place_address) type (initializer-list)

 

其中place_address必须是个指针,nitializer-list是初始化列表。

 

可以使用定位new表达式代替allocator 里的 construct函数。定位new表达式初始化一个对象的时候,可以使用任何构造函数(constructor只能使用 拷贝构造函数),并且直接建立对象。

 

例如:

 

 

new(sp)  string(b,e);

 

alloc.construct(sp+1,string(b,e));

 

       相对于 定位new表达式 析构操作的是 显示的调用析构函数。显示调用析构函数只是清除对象本身,但是并没有释放对象所占用的内存。

 

 

 

PS:以上内容全部来自经典的《C++ PRIMER》。

 

C++内存管理 内存管理是C++令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过的,除非放弃C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由对内存的支配权,还放弃了C 阅读详情

相关推荐

cpp混淆详解

C++代码混淆是一种技术,旨在通过修改代码的结构符号名称,使其难以被人类阅读理解,同时保持代码的功能性能不变。这种技术常用于保护知识产权,防止反向工程代码盗窃。

N阶二进制的博客 3049

如何提升代码的安全性 —— 代码混淆

目录一、背景1.1 Android应用安全存在多重隐患二、代码混淆2.1 代码混淆的原理2.2 代码混淆的方法2.3 常见的代码混淆方式三、 C/C++ 代码混淆3.1 Obfuscator-LLVM实现C/C++混淆3.1.1 常见的混淆方法3.1.2其他常见的C/C++混淆手段:四、代码混淆可能带来的问题 一、背景 1.1 Android应用安全存在多重隐患 代码可逆向:客户端App的逻辑能够被轻易获取逆向,得到代码程序中的敏感数据; 功能泄漏:客户端App中高权限行为功能被其他未授权的应

ZP1015 2950

C++混淆

C++混淆1. const指针1.1 指向常量的指针1.2 指针常量1.3 指向常量的指针常量2. 传值传址3. 指针4. 类5. 构造函数与析构函数5.1 构造函数5.2 析构函数5.3 总结6. 继承 1. const指针 1.1 指向常量的指针 定义一个指针,使它本身的值可变,但是它所指向的值不可变。 形式一般为 const type *name; 是否初始化无所谓 例如: const ...

u011609063的博客 1032

c/c++混淆点总结

最近学ds教材跟教辅是两种语言真的把c/c++搞的满混淆的 查阅很多资料整理了一些不同的语法点,希望自己手写代码的时候不要不懂装懂鸭~ 1,在C++中,民,局部变量可以在一个程序块内在任何地方声明,在C中,局部变量必须在程序块的开始部分,即在所有"操作"语句之前声明,请注意,C99标准中取消了这种限制。例如:在C++中,for语句中可以出现for(int i=0;i<5;i++),即定义i的...

Abigail路小雨的博客 1595

写一些c++的无效的 不影响执行效率的 混淆代码

(即“干扰阅读、对抗逆向、增加可读性负担,但不真正改变程序逻辑或效率”)通常用于代码混淆或安全场景。,它们可以插入到真实逻辑中,不会改变程序行为,但会让人更难读懂。示例2:空的 if/else 分支。示例4:死代码块,永远不会执行。示例1:无意义的变量与循环。

lydstory123的专栏 315

C++ 从堆区申请空间 newdelete

动态对象创建 1、malloc calloc realloc比较 当我们创建数组的时候,总是需要提前预定数组的长度,然后编译器分配预定长度 的数组空间,在使用数组的时,会有这样的问题,数组也许空间太大了,浪费空 间,也许空间不足,所以对于数组来讲,如果能根据需要来分配空间大小再好不 过。 所以动态的意思意味着不确定性。 为了解决这个普遍的编程问题,在运行中 可以创建销毁对象是最基本的要求。当然...

兰天禄的博客 3751

C++-类-动态对象创建1:new【摒弃C中的mallocfree函数】【创建:Person* person = new Person(“tom“)】【销毁:delete person】

换句话说,person指针指向的是一个单一的对象还是一个数组对象,由于单一对象数组对象的内存布局是不同的。当我们创建数组的时候,总是需要提前预定数组的长度,然后编译器分配预定长度的数组空间,在使用数组的时,会有这样的问题,数组也许空间太大了,浪费空间,也许空间不足,所以对于数组来讲,如果能根据需要来分配空间大小再好不过。使用了new也搭配使用了delete,问题在于Person有10个对象,那么其他9个对象可能没有调用析构函数,也就是说其他9个对象可能删除不完全,因为它们的析构函数没有被调用。

u013250861的博客 676

C++中,malloc free 与 new delete的区别

记录一下malloc 与 new 的区别。由以上代码可知,malloc与new都可以在c++中申请堆空间,不过要注意,malloc是函数,而new是一个操作符。

aaasssffx的博客 207

C++ 内存管理(建议收藏)

C++中,内存分成5个区,他们分别是栈、堆、自由存储区、全局/静态存储区常量存储区。

高空的博客 8926

【带头学C++】----- 九、类对象 ---- 9.8 动态对象创建

在创建数组时,我们通常需要预先指定数组的长度,然后编译器会为数组分配相应大小的空间。然而,在使用数组时会出现一些问题。一方面,可能会造成空间的浪费,因为数组的空间可能会过大。另一方面,可能会出现空间不足的情况。因此,对于数组来说,动态的意思表示了空间分配的不确定性。为了解决这个普遍的编程问题,最基本的要求之一就是可以在运行时创建销毁对象。虽然 C++ 提供了动态内存分配的函数(如 malloc free),可以在运行时从堆中分配存储单元,但这些函数在 C++ 中并不能很好地完成对象的初始化工作。

Phofomy的博客 1107

C++语言对象——动态对象

动态对象概述: 当我们创建数组的时候,总是需要提前预定数组的长度,然后编译器分配预定长度 的数组空间,在使用数组的时,会有这样的问题,数组也许空间太大了,浪费空 间,也许空间不足,所以对于数组来讲,如果能根据需要来分配空间大小再好不 过。 所谓动态的意思意味着不确定性。 而在程序运行中 可以创建销毁对象是最基本的要求。当然 c 早就提供了动态内存分配(dynamic memory allocation),函数 malloc free 可以在运行时从堆中分配存储单元。 然 而这些函数在 c++中不能很好

qq_45652092的博客 1496

【转载】C/C++内存管理详解

转自:http://chenqx.github.io/2014/09/25/Cpp-Memory-Management/ 内存管理是C++令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理...

amo1561的博客 102

C++ 内存管理

转自https://chenqx.github.io/2014/09/25/Cpp-Memory-Management/ 内存管理是C++令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须...

qq_27838651的博客 154

25 C++ - 动态对象创建

当我们创建数组的时候,总是需要提前预定数组的长度,然后编译器分配预定长度的数组空间,在使用数组的时,会有这样的问题,数组也许空间太大了,浪费空间,也许空间不足,所以对于数组来讲,如果能根据需要来分配空间大小再好不过。 所以动态的意思意味着不确定性。 为了解决这个普遍的编程问题,在运行中可以创建销毁对象是最基本的要求。当然c早就提供了动态内存分配(dynamic memory allocation...

阿甘兄 966

C++指针核心原理:从内存地址到动态内存管理的全面解析

在计算机编程中,内存地址是数据存储访问的基础概念,它标识了数据在内存中的具体位置。指针作为存储内存地址的变量,其核心原理在于通过地址间接访问操作数据,实现了对内存的直接控制。这一机制的技术价值在于提供了高效的数据访问方式,避免了不必要的数据复制,从而提升了程序性能。在应用场景上,指针广泛应用于动态内存管理、函数参数传递、构建复杂数据结构(如链表树)以及实现回调函数等。理解指针与数组的紧密关系、掌握动态内存分配与释放(new/delete),并警惕悬空指针内存泄漏等常见陷阱,是编写健壮、高效C++程序

711

C/C++内存管理详解

内存管理是C++令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过的,除非放弃C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由对内存的支配权,还放弃了C...

weixin_30535913的博客 65

C++内存管理详解

[导语] 内存管理是C++令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过的,除非放弃C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由对内存的支

chaoguodong的专栏 1276
上一篇: 对于静态成员指针的出现的问题
下一篇: Traits技术
hycoldrain
博客等级 码龄20年 7粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值