我遇到了一个奇怪的问题,我创建了这个简单的程序来演示它。我知道代码本身没有多大意义,但我想突出一些我不理解的东西。
#include <iostream>
using namespace std;
class tempClass{
public:
float n;
tempClass(){};
~tempClass(){} //VERY IMPORTANT LINE
void* operator new[](size_t size);
};
void* tempClass::operator new[](size_t size){
tempClass* a;
a= ::new tempClass[2];
for (int i = 0; i < 2; i++)
{
a[i].n = i*10;
}
cout << a << endl;
return a;
}
int main(){
tempClass* a;
a = new tempClass[2];
cout << a << endl;
cout << a[0].n << endl;
return 0;
}
在代码中,我已经为我创建的类重载了operator new。但是,函数的行为会发生变化,具体取决于我是否包含类的析构函数。我注意到,如果我不包含析构函数,一切正常,而如果我这样做,指针a
的返回值将始终增加8
。因此,在此示例中,如果我包含析构函数,则程序的最后cout
将打印20
,如果不包含析构函数,则0
将打印Function TrimTrailingZeroes(BigNumber As String) As String
Dim i As Integer
For i = Len(BigNumber) To 1 Step -1
If Mid(BigNumber, i, 1) <> "0" Then
TrimTrailingZeroes = Left(BigNumber, i)
Exit Function
End If
Next i
TrimTrailingZeroes = BigNumber
End Function
。为什么会这样?
答案 0 :(得分:4)
Array-new-expressions将未指定数量的开销传递给分配函数(即您的operator new
重载)。这是为了允许实现记录数组元素的数量,以便在删除时调用析构函数。
如果您的实现检测到类没有需要析构函数被调用(因为它可以轻易破坏),它可能会选择不需要相同数量的开销
正式措辞是8.3.4 [expr.new] p11:
当 new-expression 调用分配函数并且该分配尚未扩展时, new- 表达式将请求的空间量作为类型的第一个参数传递给分配函数
std::size_t
。 该参数不得小于正在创建的对象的大小;它可能更大 仅当对象是数组时才创建对象的大小。 [...]
请注意,开销是未指定的,因此原则上每次调用都可能有所不同! (这也是placement-array-new is unusable的原因。)但是,许多实现使用的Itanium ABI在&#34; array cookie&#34;工作,并与您的经验相匹配。
答案 1 :(得分:2)
这是Itanium CXX ABI array operator new[]
cookie:
当operator new用于创建新数组时,通常会存储cookie以记住分配的长度(数组元素的数量),以便可以正确地释放它。 [...]
,则不需要cookie
如果数组元素类型T有一个简单的析构函数(12.4 [class.dtor]) [...]
析构函数(除了在类中定义为= default
之外的析构函数)是非平凡的。