惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
AI
AI
博客园 - 三生石上(FineUI控件)
腾讯CDC
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
H
Hackread – Cybersecurity News, Data Breaches, AI and More
雷峰网
雷峰网
NISL@THU
NISL@THU
S
Schneier on Security
T
Threatpost
T
Tenable Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
IT之家
IT之家
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
C
Cybersecurity and Infrastructure Security Agency CISA
P
Privacy & Cybersecurity Law Blog
I
Intezer
Microsoft Azure Blog
Microsoft Azure Blog
月光博客
月光博客
T
Threat Research - Cisco Blogs
SecWiki News
SecWiki News
AWS News Blog
AWS News Blog
博客园 - Franky
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Proofpoint News Feed
V
V2EX
Recorded Future
Recorded Future
Microsoft Security Blog
Microsoft Security Blog
S
Secure Thoughts
Google DeepMind News
Google DeepMind News
MongoDB | Blog
MongoDB | Blog
Apple Machine Learning Research
Apple Machine Learning Research
Project Zero
Project Zero
PCI Perspectives
PCI Perspectives
G
GRAHAM CLULEY
Help Net Security
Help Net Security
Cloudbric
Cloudbric
Recent Announcements
Recent Announcements
V
Visual Studio Blog
Hacker News: Ask HN
Hacker News: Ask HN
N
News and Events Feed by Topic
C
CERT Recently Published Vulnerability Notes
The Cloudflare Blog
Forbes - Security
Forbes - Security
C
Cisco Blogs
O
OpenAI News
www.infosecurity-magazine.com
www.infosecurity-magazine.com

Victrid's Personal Site

斯普拉遁3打工模式联机网络过程分析 DHCP无类型静态路由──一个摆设 配置透明代理,实现无感上网 Generating Unlimited Grammar: A Messenger Perspective LaTeX插入其他PDF中的矢量图 光速不变原理和迈克尔孙──莫雷实验 交大葡萄演义 调试微信内置浏览器 欧悌甫戎篇 苏格拉底的申辩篇 LCA 最近公共祖先 弥罗斯人的辩论 埃斯库罗斯作品:波斯人、阿伽门农 电路理论资料 Coronavirus: A Humanitarian Crisis 雨夜 linux配置SSR 二叉堆的实现 懒政 Flipped: A Love Story 我宁可呆在这样的疯人院里 谈新发本地病例 勇敢与智慧 Powerful but Limited Drafted VLC Libva Error Troubleshooting Ring-Fit新上手 政治艺术化与艺术政治化 动态规划——从分割等和子集入手 被背叛的革命 (1) Everything About DPT-RP1 When Using LINUX HTTP STATUS 451 二分法——重复情形 鸽巢排序与桶排序 为什么要写博客 系统更换 动窗法与前缀和——简单实践 非类型模板参数 判断的短路规则 CodeBlocks重装 C-Style String Operation
Placement New
Victrid · 2020-04-01 · via Victrid's Personal Site

前几天写vector,可把我难倒了。最开始是一个测试用例,没有默认的构造函数,这个时候应该怎样去处理内存的分配。

我想到,既然一个元素的大小,即sizeof()是固定的,我们就可以先申请这个空间,等到需要使用的时候再赋值。

memcpy() 失败

虽然只学过C++化的简化版C语言,但我想到了malloc()方法,这就是一个只申请空间,不去填充空间的方法。

这对于传统的数据,就是说所谓的POD(Plain Old Data)是很好的。我的整个实现逻辑也是memcpy(),这样的处理速度快的多。

但是不是POD的类,占用了堆来存储部分内容,在他的存储空间里只存储了指向堆的指针。所以memcpy()只执行了浅拷贝,拷贝的实际上是指针,它指向的堆内存储是不变的。当原对象析构释放堆的时候,拷贝对象就被破坏了;被覆盖的对象没有进行析构而是直接被覆盖,内部申请的堆内存就被泄漏。

同样,当被覆盖的地方原本不存在对象,即只分配了内存却没有初始化内存空间时,如果直接调用类的赋值,这个赋值方法是不能检测原来的对象是否正确的。一旦有针对原指向堆内存的指针,现在是随机指针进行的操作,例如直接向动态数组发起memcpy(),就会出现段错误,或者内存的错误覆盖。

所以,凯撒的归凯撒,经过查阅资料,我找到了下面两个C++的处理方法。

为什么我最开始不用new呢?因为new在调用的时候会自动调用构造函数,而一个用例没有默认构造函数,new就会出错。

怎么解决呢?经过资料的学习,我找到了placement new这个用法。实际上,new和delete是通过以下的过程实现的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
A* p=new A;					B* t=new B[_NUM];
delete p; delete [] t;



operator new(sizeof(A)); operator new[](_NUM*sizeof(B));


new(p) A(); for(size_t in=0;in<_NUM;in++)
new(t+in*sizeof(B)) B();



p->~A(); for(size_t in=0;in<_NUM;in++)
(t+in*sizeof(T))->~B();

operator delete p; operator delete [] t;

过程中的placement new实际上就是按需调用构造函数,而operator new/delete则是只申请内存而不初始化,和malloc/free功能是一致的。好像构造函数是不能够显式调用的,所以placement new来解决这个问题。

Author: Victrid

Permanent Link: https://victrid.dev/2020/nt-new/

License: Copyright (c) 2025 victrid Terms of Use

Ads by Google

Read our privacy policy on how these personalized advertisements are delivered to you.

For your reading experience, we provide full-text RSS feeds. Although math formulas cannot be displayed well, the interface can be adjusted as you like and there are no ads.