Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >placement new

placement new

作者头像
JIFF
发布于 2019-08-02 07:24:25
发布于 2019-08-02 07:24:25
1.1K00
代码可运行
举报
文章被收录于专栏:Toddler的笔记Toddler的笔记
运行总次数:0
代码可运行

C++11 中,形如 new(buffer)T; 的语句即为 placement new 语法

如何让一个已经 contructed 的 object 重新调用其 constructor?placement new 就是答案。

placement new 可以指定 "new/新建" 的内存的具体位置。

  • there's no "placement delete". with placement new, you could "new" memory in stack/heap/static/thread_local storage area.
  • there's no book keeping area for placement new. The "allocated" size is exactly the same with the size of the object which was newed.
    • (注意"new/新建/allocated"是引号,因为实际上并没有新的内存被 alloc)
  • placement new 出来的 object,"销毁"时不会自动调用其 destructor,如果需要的话,可以手动调用它
    • (为什么"销毁"是引号?难以言喻,读完本篇应该可以意会)

首先补充一点:一般来说,C++ 有四种 storage categories

  • static storage duration: 即 global 和 staic local
  • thread_local storage duration: C++11 new keyword. 与线程同生同死
  • dynamic storage duration: 即存在于 Heap,例如在 Linux x64 中地址从小到大增长
  • automatic storage duration: 即存在于 Stack,例如 function frame
  • 第五种 register 在 C++ 中俨然已如空气,一般编译器都会直接忽略它。

举一个 auto/thread_local/static 的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct T {
    int val;
    T(int v) : val(v) {}
    T(int a, int b) : val(a + b) {}
    ~T() {
        cout << "val: " << val << endl;
    }
};
{
    // static char .. | thread_local char ..
    char buffer[16];
    T* ptr = new (buffer) T(10);

    // 此时 ptr->val == 10, ptr的值 == buffer的首地址
    cout << ptr->val;
}
// 离开 scope,对于 auto 类型的 char buffer[10],其内存被回收。
// ptr->~T() 不会被调用。注意是 stack 中的 buffer 数组的析构函数被调用。
// 当然对于 buffer 这样的 POD 并没有析构函数
//
// 如果 buffer 是 thread_local,则当 thread 结束并被join 或者 detach 后,
// buffer 的内存被回收。
//
// 如果 buffer 是 static,则当 process exit 时,process 所有的内存被操作系统回收,
// 当然也包括 buffer。

再举一个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    // class T constructor T(int);
    T t(1);
    T* ptr = &t;

    // 这里调用它只是为了打印。实际使用中析构函数会释放一些资源,
    // 对应构造函数会创建一些资源。
    ptr->~T();

    // class T constructor T(int, int);
    new (ptr) T(2, 3);
}
// t 的生命结束时,t.~T() 再次被调用

再举一个 heap 的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    // 申请 sizeof(T) 的内存 + 一定数量的 book keeping 内存
    T* ptr = new T(1);

    // T(1)的内存被直接覆盖了,注意其 destructor 没有被调用
    T* ptr2 = new (ptr) T(2, 3);

    // ptr->~T() 被调用。一共有:一次底层 malloc,两次 ctor,
    // 一次 dtor,一次底层 free 被调用。
    // 同时 delete()库函数 会 free book keeping area
    delete ptr;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Toddler的笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入理解多级缓存必备知识--线程局部变量
CPU从内存中读取数据的时候是一次读一个cache_line到 cache中以提升效率, 一般情况下cache_line的大小是64 byte(64Bytes也就是16个32位的整型) 这就是CPU从内存中捞数据上来的最小数据单位
早起的鸟儿有虫吃
2025/05/23
770
深入理解多级缓存必备知识--线程局部变量
C++内存管理:深入理解与高效实践
在C++编程的世界里,内存管理是一项至关重要的技能。它不仅是性能优化的关键,更是确保程序稳定性和安全性的基石。C++赋予程序员直接操作内存的能力,这既是一种强大的武器,也可能成为潜在的陷阱。因此,掌握有效的内存管理策略,对于每一位C++开发者来说,都是通往高手之路的必经之路。
suye
2025/05/27
1170
玩转C++内存管理:从新手到高手的必备指南
C++中的内存管理是编写高效、可靠程序的关键所在。C++不仅继承了C语言的内存管理方式,还增加了面向对象的内存分配机制,使得内存管理既有灵活性,也更加复杂。学习内存管理不仅有助于提升程序效率,还有助于理解计算机的工作原理和资源分配策略。
平凡之路.
2025/06/02
870
玩转C++内存管理:从新手到高手的必备指南
C++ delete的三种面貌
为了避免内存泄漏,每个动态内存分配必须有与一个相反的解除分配(Deallocation)操作对应,所以C++中有new操作,那么就存在相反的delete操作,new与delete的关系,就像C语言中malloc()与free()的关系,分别负责内存的申请与释放,只不过C++中的new与delete赋予了其它的功能。当我们使用delete运算符来释放一个由new创建的对象时,我们应该清楚delete完成的工作有: (1)调用对象析构函数; (2)调用operater delete()函数释放内存空间。
恋喵大鲤鱼
2019/02/22
1.4K0
【C++】C/C++内存管理详解
在之前的C语言中就有提到动态内存管理 【C语言】动态内存管理,那么在C++中又是怎么样的呢?话不多说,正文开始。
zxctscl
2024/03/08
1390
【C++】C/C++内存管理详解
智能指针
刚学编程时,最常听到的一句话是不是“new 的内存用完要记得 delete,不然会造成内存泄漏”?然而事实上是:
JIFF
2019/08/02
1.2K0
C++内存管理深度总结(近万字详解!)
在C语言中,动态内存管理主要通过malloc、calloc、realloc和free这四个函数进行。以下是一个简化的代码示例,展示了如何在C语言中使用这些函数来动态分配、使用和释放内存:
suye
2024/10/16
2760
C++ ⾼性能内存池
当前项⽬是实现⼀个⾼并发的内存池,他的原型是google的⼀个开源项⽬tcmalloc,tcmalloc全称 Thread-Caching Malloc,即线程缓存的malloc,实现了⾼效的多线程内存管理,⽤于替代系统的内存分配相关的函数(malloc、free)。
ljw695
2025/02/27
1071
C++ ⾼性能内存池
阿里一面凉经:深入理解ThreadLocal变量
在线程创建时,运行时(glibc + dynamic linker)会为每个线程分配两个独立区域:
早起的鸟儿有虫吃
2025/05/14
970
阿里一面凉经:深入理解ThreadLocal变量
c语言智能指针 附完整示例代码
资源获取即初始化 (Resource Acquisition Is Initialization, RAII),RAII是一种资源管理机制,资源的有效期与持有资源的对象生命期严格绑定,即由对象的构造函数完成资源的分配,由析构函数完成资源的释放,总结一句话就是 用对象来管理资源
cpuimage
2018/08/19
2.6K0
c语言智能指针 附完整示例代码
C++ new的三种面貌
C++中使用new运算符产生一个存在于Heap(堆)上的对象时,实际上调用了operator new()函数和placement new()函数。在使用new创建堆对象时,我们要清楚认清楚new的三种面貌,分别是:new operator、operator new()和placement new()。
恋喵大鲤鱼
2019/02/22
6000
C++ new的三种面貌
智能指针入门 auto_ptr
所谓智能指针,就是可以随便申请而无需管理自动释放,就像 java 或 C# 的垃圾回收机制一样。我们无需关心销毁只管尽情的申请,系统提供了一个 auto_ptr 类可以使用这样的功能。后面我们也会用简单的代码示例介绍 auto_ptr 内部是如何实现的。代码如下:
我与梦想有个约会
2023/10/20
1840
智能指针入门 auto_ptr
C++ new的三种面貌
C++中使用new运算符产生一个存在于Heap(堆)上对象时,实际上调用了operator new()函数和placement new()函数。在使用new创建堆对象时,我们要清楚认清楚new的三种面貌,分别是:new operator、operator new()和placement new()。
恋喵大鲤鱼
2018/08/03
5.6K0
C++ new的三种面貌
【C/C++】——小白初步了解——内存管理
特点:如果新大小大于原大小,新分配的内存区域中的内容是不确定的;如果新大小小于原大小,超出的内容将被丢弃。
小李很执着
2024/06/15
1570
看完这篇你还能不懂C语言/C++内存管理?
C 语言内存管理指对系统内存的分配、创建、使用这一系列操作。在内存管理中,由于是操作系统内存,使用不当会造成毕竟麻烦的结果。本文将从系统内存的分配、创建出发,并且使用例子来举例说明内存管理不当会出现的情况及解决办法。
C语言与CPP编程
2020/12/02
6100
看完这篇你还能不懂C语言/C++内存管理?
[C++] 深度剖析C_C++内存管理机制
定位new表达式语法:void* operator new(size_t, void* place) noexcept { return place; }
DevKevin
2024/07/25
1310
[C++] 深度剖析C_C++内存管理机制
【C++内存管理】:new与delete,operator new与operator delete
📝前言: 上篇文章【C++高潮:类与对象】我们对C++的类与对象的知识点进行了讲解。 这篇文章我们在C语言内存管理的基础上探讨一下C++内存的管理: 1,C/C++内存分布 2,C语言内存管理 3,C++内存管理方式 4,operator new与operator delete 5,new和delete的实现原理 6,定位new表达式 7,malloc/free和new/delete的区别
用户11029137
2025/03/12
2320
C++中的定位放置new(placement new)
一般来说,使用new申请空间时,是从系统的“堆”(heap)中分配空间。申请所得的空间的位置时根据当时的内存的实际使用情况决定的。但是,在某些特殊情况下,可能需要在程序员指定的特定内存创建对象,这就是所谓的“定位放置new”(placement new)操作。
恋喵大鲤鱼
2018/08/03
1K0
计算机考研复试C语言常见面试题「建议收藏」
P.S. 我当初整理的时候是word,直接复制过来的话代码不会自动变成CSDN的代码块,所以代码我是一段一段重新标记为CSDN代码段的,这样大家看起来舒服点
全栈程序员站长
2022/09/27
1.8K0
计算机考研复试C语言常见面试题「建议收藏」
C++内存管理(new operator/operator new/operator delete/placement new)
我们平时使用的new是new操作符(new operator),就像sizeof一样是语言内置的,不能改变它的含义,功能也是一样的
WindSun
2019/09/02
1.7K0
C++内存管理(new operator/operator new/operator delete/placement new)
相关推荐
深入理解多级缓存必备知识--线程局部变量
更多 >
LV.0
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验