对于对齐,:: operator new(size_t n)和new char [n]之间有什么区别?

时间:2011-08-14 17:14:33

标签: c++

关于对齐,我不明白显式调用T* t = (T*) ::operator new(sizeof(T))T* t = (T*)new char[sizeof(T)]之间的区别,其中T是类似C的结构。< / p>

在“C ++ Solutions Companion to the C ++ Programming Language,Third Edition”一书中(见练习12.9),作者说:“注意,不应该使用表达式new char [n]来分配原始内存因为该内存可能无法满足T的对齐要求,而全局运算符new的显式调用可以保证产生与任何C ++对象充分对齐的存储。“。我在互联网上阅读的一篇文章中也提到了这一点:http://www.scs.stanford.edu/~dm/home/papers/c++-new.html(参见“删除与删除[]和免费”段落。

另一方面,在我之前的帖子Data alignment in C++, standard and portability中,一个人引用了标准,加上引号末尾的一个注释与上述人员相矛盾:

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

我很困惑。你能否按照标准告诉我谁在这里,如果::operator new()new char[]有什么不同?

3 个答案:

答案 0 :(得分:2)

没错,new char[n]委托给operator new[](size_t),见5.3.4“新”§8:

  

new-expression 通过调用分配函数来获取对象的存储空间[...]   如果分配的类型是数组类型,则分配函数的名称为operator new[]

因此,前者绝不可能以某种方式产生“不那么对齐”的记忆而不是后者。

可悲的是,当谈到技术细节时,大多数C ++书籍都很简单。

答案 1 :(得分:1)

C ++98§3.7.3.1/ 2,关于分配函数:

  

返回的指针应适当对齐,以便它可以转换为指针   任何完整的对象类型,然后用于访问分配的存储中的对象或数组

与你关于新表达式的§5.3.4/ 10的引用一起,“一个新表达式传递了数量......”,这意味着new char[n]无法提供较弱的对齐保证,它可以'不那么对齐。

干杯&amp;第h。,

答案 2 :(得分:0)

标准的不同版本之间存在混淆。较旧的标准没有使new char[n]和新的标准成为保证。

注意new char[n]可能不会返回从底层operator new(size_t)返回的相同指针的两种情况下的位 - 这是因为在分配数组时,运行时可能会使用开头的空格被分配的块(返回operator new(size_t)和返回new char[n]之间的空间)来存储数组的大小 - 并且该大小可能不需要完整的最坏情况对齐填充。实现不是 required 来执行此操作 - 它可能会注意到,因为char没有析构函数,所以它不需要记录数组的大小以了解析构函数调用的数量在调用delete[]时进行。但是实现可以自由地统一处理所有数组。