提问人:Pavel Dubsky 提问时间:12/6/2012 最后编辑:Pavel Dubsky 更新时间:5/15/2014 访问量:320
运算符 new[] 不接收额外的字节
Operator new[] does not receive extra bytes
问:
我有这样的代码
#include <cstdlib>
class Foo
{
int m_data;
public :
Foo() : m_data(0) { }
/*~Foo()
{
}*/
static void* operator new[](const size_t size)
{
return malloc(size);
}
static void operator delete[](void* data)
{
free(data);
}
};
int main()
{
Foo* objects = new Foo[5];
delete [] objects;
}
在这种情况下,我根据需要将运算符 new 重载的值作为 20 个字节()。但是,如果我取消对析构函数的注释,我会得到 24 个字节。是的,我现在这些额外的字节用于存储分配的内存大小,并且等于 .我不明白为什么只有在我显式实现析构函数时才能获得它们。如果我不这样做,编译器应该做完全相同的事情,或者我错过了什么?size
sizeof(int) * 5
size
sizeof(size_t)
我已经在 MSVS 2010 和 2012 上尝试过了。针对 Win32 编译。
答:
如果编译器不需要调用析构函数,则不需要记住要调用多少个析构函数。如果您有一个需要解构的数据成员,则不会观察到这种行为,例如 ,因为编译器始终需要解构它。std::string
from 请求的“额外字节”不用于“存储分配的内存大小”,正如您似乎认为的那样。它们用于存储数组中元素的数量,以便知道要调用多少析构函数。在您的示例中,析构函数是微不足道的。没有必要打电话给他们。因此,无需分配这些额外的字节并存储元素计数。new[]
operator new[]
delete[]
“分配的内存大小”(即以字节为单位的块大小)是完全不同的故事。它由较低级别的分配器独立存储和检索 - 在您的示例中。malloc/free
换句话说,在一般情况下,由 分配的内存块在实际数据前面有两组额外的字节:以字节为单位的块大小(由 引入)和元素计数(由 引入)。第二个是可选的,如您的示例所示。第一个通常始终存在,因为它是由 无条件分配的。也就是说,即使您仅请求 .这些额外的字节将用于存储块大小(以字节为单位)。new[]
malloc
new[]
malloc
malloc
20
20
malloc
后者也发生在你的例子中。你根本看不到它,因为它发生在里面.malloc
评论