2011-08-14 135 views
3

关于比对,我不明白T* t = (T*) ::operator new(sizeof(T))T* t = (T*)new char[sizeof(T)]的显式调用之间的差异,其中T是一个类C结构。:: operator new(size_t n)和new char [n]在对齐方面有什么区别?

在这本书中的“C++解决方案伴侣对C++编程语言,第三版”(见练习12.9),作者说:“需要注意的是一个不应使用表达新的char [N]分配原始内存,因为该内存可能不满足T的对齐要求,而全局运算符new的显式调用将保证产生足够与任何C++对象对齐的存储。“”。这也是我在互联网上阅读的文章中提到的:http://www.scs.stanford.edu/~dm/home/papers/c++-new.html(请参阅“删除与删除[]和免费”段落)。

在另一方面,在我以前的帖子Data alignment in C++, standard and portability一个家伙引用的标准,再加上这违背上面的人报价的最后一个音符:

一种新的表达传递的空间量请求分配函数作为std :: size_t类型的第一个参数,该参数不得小于正在创建的对象的大小;它可能大于只有当对象是数组时才创建的对象的大小。对于char和unsigned char数组,new-expression的结果与分配函数返回的地址之间的差异应是任何大小为no的对象类型的最严格基本对齐要求(3.11)的整数倍大于正在创建的数组的大小。 [注意:因为分配函数被假定为返回指向存储器的指针,这些指针对于具有基本对齐的任何类型的对象都适当地对齐,所以这种对数组分配开销的约束允许分配其他类型的对象稍后将放置到其中的字符数组的通用惯用法。 - 注完]

我很困惑,你能告诉我,谁是这里根据标准,并在情况下,为什么是new char[]

回答

2

这是正确的,new char[n]委托给operator new[](size_t)::operator new()不同?见5.3.4“新建”§8:

新表达通过调用分配函数[...] 如果所分配的类型是一个数组类型,分配获得用于对象存储功能' s的名字是operator new[]

因此,绝对没有办法前者以某种方式产生比后者更“对齐”的内存。不幸的是,当谈到技术细节时,大多数C++书籍都只是简单的吸引。

1

C++ 98§3.7.3.1/ 2,约分配功能:

返回须适当地对准,使得它可以被转换为任何 完整的对象的类型,然后指针所使用的指针访问该对象或阵列中分配

连同您的§5.3.4/ 10大约报价新表达式,“A new表达式的光量...”的存储,这意味着new char[n]可以” t提供较弱的对齐保证,它不能少对齐。

干杯&第h。,

+1

's/new char(n)/ new char [n] /' – fredoverflow

+0

谢谢!现在修好了! –

0

的混乱是不同版本的标准之间。旧标准没有保证new char[n]和新的标准。

请注意,在两种情况下,new char[n]可能不会返回与底层operator new(size_t)相同的指针 - 这是因为在分配数组时,运行时可能会使用分配块开始处的空间(空间在operator new(size_t)返回值和new char[n]返回值之间)来存储数组的大小 - 并且该大小可能不需要完全最坏情况的对齐填充。一个实现不是需要来做到这一点 - 它可能会注意到,因为char没有析构函数,所以它不需要记录数组的大小来知道在调用delete[]时要调用多少析构函数。但是一个实现可以自由地处理所有的数组。

相关问题