请考虑以下代码,其中包含一个包含new
和new[]
重载的类:
#include <iostream>
class my_class {
public:
my_class() {};
my_class(const my_class& rhs) {};
~my_class() {};
//the constructor also as applicable.
void * operator new(size_t sz);
void * operator new[](size_t sz);
void operator delete(void * ptr);
void operator delete[](void * ptr);
private:
};
void * my_class::operator new(size_t sz)
{
std::cout << "at operator new, sz is: " << sz << std::endl;
}
void * my_class::operator new[](size_t sz)
{
std::cout << "at operator new[], sz is: " << sz << std::endl;
}
void my_class::operator delete(void * ptr)
{
std::cout << "at operator delete, ptr is: " << ptr << std::endl;
}
void my_class::operator delete[](void * ptr)
{
std::cout << "at operator delete[], ptr is: " << ptr << std::endl;
}
int main(int argc, char ** argv)
{
my_class * ptr = new my_class;
my_class * arr_ptr = new my_class[1];
return 0;
}
在终端(Cygwin)中运行,我看到:
at operator new, sz is: 1
at operator new[], sz is: 9
调用sz == 9
时为什么operator new[]
?是谁设定的?它取决于什么(例如页面大小?)?
答案 0 :(得分:2)
新{em>表达式,如new my_class
,不仅仅是调用operator new
; operator new
仅分配内存,其参数是应分配的内存大小。
sz
的参数operator new
为1,因为这是最小的可能实例; sizeof(my_class)
为1。
sz
的参数operator new[]
为9,因为new[]
- 表达式(new my_class[1]
)需要多少内存来分配1个大小为1的实例的数组
“额外”8用于跟踪诸如有多少元素之类的事情 “额外”内存的大小取决于实现。
答案 1 :(得分:1)
runtime&#34;设置&#34;调用运算符new
时的值。传递了一个隐含的sizeof
。它与调用成员函数的情况相同,但没有隐式地将指针传递给当前实例this
。
在你的情况下,你有一个没有成员的类,所以理论上它的大小应该为零,但是C ++分配一个字节(由于对象必须至少是可寻址的)。这就是为什么第一次分配的结果为1的原因(假设您修复了运算符new/new[]
以返回某些内容,直到那时您有UB)。由于C ++如何表示动态数组,第二个分配返回9,它将某个头放在某处(实现已定义),因此它识别它是一个数组(因此在调用operator delete[]
时,后者行为正常)并且可能是由于填充。