placement new的问题

anank 2007-05-03 10:37:12
关于 placement new 的问题:
----------------
在网上找了很多关于placement new的介绍,有很多都是这样说的;

引用:
使用方法
第一步 缓存提前分配
class Task {/*..*/};
char * buff = new [sizeof(Task)]; //分配内存
第二步:对象的分配
Task *ptask = new(buff) Task
第三步:使用
ptask->suspend();
第四步:对象的毁灭
ptask->~Task(); //调用外在的析构函数
第五步:释放
你可以反复利用缓存并给它分配一个新的对象(重复步骤2,3,4)如果你不打算再次使用这个缓存,你可以象这样释放它
delete [] buff;
跳过任何步骤就可能导致运行时间的崩溃,内存泄露,以及其它的意想不到的情况。如果你确实需要使用placement new,请认真遵循以上的步骤。


---------
问题:
1> 第一步改成这样行不行?
char *buff = operator new [sizeof(Task)] ; // 用operator 来分配空间,不作初始化
2> 还有一些参考资料上说placement new和内存对齐的关系比较大,如果使用不档,会造成大的问题。内存对齐我是知道的,但是请问会造成什么问题?(举个简单例子看看)应该怎么避免(或者解决)这样的问题??
...全文
455 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
emmett 2007-08-06
  • 打赏
  • 举报
回复
堆内存就可以保证没有对起问题吗?
如果堆是8字节对其的,而我的class要求16字节对齐,怎么办?
anank 2007-05-07
  • 打赏
  • 举报
回复
说的好极了。
antterminator 2007-05-06
  • 打赏
  • 举报
回复
deng2000() 说的不错
deng2000 2007-05-05
  • 打赏
  • 举报
回复
惭愧,不经意把大牛的名字都敲错了,应该是Herb Sutter.
再补充一句, 关于以栈内存inplacement new会不会引起对齐问题是有争论的.有些人坚持说不会有问题.因为牵涉到底层硬件,这已不单是一个C++的问题了. 我们大可不必关心这些争论. 不管怎样,以堆内存inplacement new是绝对安全的.
deng2000 2007-05-05
  • 打赏
  • 举报
回复
高手都度假去了,就让我冒充一下高手,呵呵
(1)
可以,但你有个笔误: 应该是operator new (sizeof(Task)), 而不是operator new [sizeof(Task)]. 顺便说一句,用你的方法和直接用new char[sizeof(Task)]差不多,因为char没有构造函数,也就没有初始化代价, 之不过你用operator new()申请内存,而后者用的是operator new[]()

(2)
对齐概念你很清楚,我就不用多解释了.有些系统要求(不是编译器的要求,而是操作系统甚至硬件的要求)对象的起始地址要是某个数(例如8)的倍数.不符合这一要求可能会引起严重后果.我们一般写程序时无需多虑这一点,是因为编译器作了以下两件事情:
1. 栈上的对象(注意,是类对象,char类型就无需了,后面还会提到)保证放在对齐地址上.
2. 用malloc, operator new()等申请的堆内存的起始地址都已对齐.
因此不管是栈对象和new出来的堆对象,地址都是对齐的. So far so good, 但inplacment new带来一个微妙的问题. 设想一下下面的语句:
char buf[sizeof(T)];
T* ptr = new (buf) T();
因为buf是char数组,编译器没有义务把它放在对齐地址上,因此,接下来ptr所指的T对象可能有对齐问题!
通过这些分析我们就很明白了,防止placement new的对齐错很简单: 永远不要以栈地址来inplacement new, 而要先申请堆内存.
btw, 关于此问题Hutter的大作<<Exceptional C++>>上有很精彩的描述.请参看其中的Item 30: The "Fast Pimpl" Idiom


  • 打赏
  • 举报
回复
char * buff = new [sizeof(Task)]; //分配内存????????????????????
char * buff = new char[sizeof(Task)];这样吧

这个代码能编译过去么?
char *buff = operator new [sizeof(Task)] ;// 用operator 来分配空间,不作初始化


调整边界?不太懂这个
anank 2007-05-05
  • 打赏
  • 举报
回复
晕,竟然没一个人回。
------------
C++板的高手这么多,怎么就没有回帖的?分少吗?

内存边界怎么人工调整?可以人工调整吗?

65,213

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧