有一个单独的"operator new []"的目的是什么?

sha*_*oth 12 c++ memory-management

看起来operator newoperator new[]签名完全相同:

void* operator new( size_t size );
void* operator new[]( size_t size );
Run Code Online (Sandbox Code Playgroud)

并且完全相同:要么返回指向足够大的原始块(未以任何方式初始化)内存的指针,要么抛出异常.

operator new当我创建与物体内部调用newoperator new[]-当我创建对象的数组new[].C++内部以完全相同的方式调用上述两个特殊函数,我看不出这两个函数如何具有不同的含义.

具有完全相同的签名和完全相同的行为的两个不同功能的目的是什么?

Mik*_*our 7

可以覆盖运算符(对于特定类,或在命名空间内,或全局),如果要以不同于数组分配的方式处理对象分配,则允许您提供单独的版本.例如,您可能希望从不同的内存池中分配.


CB *_*ley 7

我对此有一个相当不错的看法,并且直言不讳从界面角度来看没有理由.

我能想到的唯一可能的原因是允许的优化提示的实施,operator new[]有可能在被称为分配较大的内存块; 但这是一个非常非常脆弱的假设,因为你可能new有一个非常大的结构或者new char[2]实际上并不算大.

请注意,operator new[]不会为数组计数或任何内容添加任何神奇的额外存储空间.这是的工作new[]操作员工作了多少开销(如果有的话)需要,并通过正确的字节计数operator new[].

[使用gcc进行的测试表明,new[]除非正在构造的数组成员的类型具有非平凡的析构函数,否则不需要额外的存储空间.

从接口和合同的角度来看(除了要求使用正确的相应解除分配功能)operator new并且operator new[]是相同的.


san*_*koz 6

在C++的设计和演变中(第10.3节),Stroustrup提到如果对象X的new运算符本身用于分配对象X的数组,那么X :: operator new()的编写者将不得不处理数组分配这也不是new()的常见用法,也增加了复杂性.因此,不考虑使用new()进行数组分配.然后,没有简单的方法为动态数组分配不同的存储区域.解决方案是为数组提供单独的allocator和deallocator方法:new []和delete [].


Ste*_*sop 5

一个目的是它们可以由用户单独定义.因此,如果我想将单个堆分配的对象中的内存初始化为0xFEFEFEFE,将堆分配的数组中的内存初始化为0xEFEFEFEF,因为我认为它将帮助我进行调试,那么我可以.

这是否值得,这是另一回事.我想如果你的特定程序主要使用非常小的对象和非常大的数组,那么你可以分配不同的堆,希望这会减少碎片.但同样,您可以识别分配大型数组的类,并仅覆盖operator new[]这些类.或者operator new可以根据大小在不同的堆之间切换.

实际上,要求的措辞有所不同.一个为任何指定大小的对象分配内存,另一个为任何指定大小的数组分配内存.我认为没有任何区别 - 大小为1的数组肯定与对象具有相同的对齐 - 但我可能会弄错.默认情况下,数组版本返回与对象版本相同的事实强烈暗示没有区别.或者至少对象的对齐要求比阵列上的对齐要求更严格,我无法理解......

  • 哦,是的,如果`sizeof(T [1])!= sizeof(T)`,整个数组大小计算`sizeof array/sizeof array [0]`将是完全错误的,我很确定那个常见的数组大小计算很明确. (2认同)