运营商新的[]没有收到额外的字节(Operator new[] does not receive e

2019-07-04 16:21发布

我有这样的代码

#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;
}

在这种情况下我接收的值size在操作者新的过载如20个字节,因为我想( sizeof(int) * 5 )。 但是,如果我去掉析构函数,我得到size为24个字节。 是啊,我现在说这些额外的字节用于存储分配内存的大小,等于sizeof(size_t) 我不明白为什么我让他们只有当我明确实现析构函数。 如果我不这样做,编译器应该做同样的事情或者我失去了一些东西?

我试过,于2010年MSVS和2012年编译为Win32。

Answer 1:

通过要求“额外字节” new[]operator new[]不习惯“存储分配的内存大小”,你似乎认为。 它们被用来存储数组中元素的个数 ,从而使delete[]会知道有多少析构函数调用。 在您的例子析构函数是微不足道的。 有没有必要给他们打电话。 所以,没有必要分配这些额外的字节和存储元素计数。

在“已分配存储器的大小”(即以字节为单位的块的尺寸)是一个完全不同的故事。 它是存储和下级分配独立检索-中malloc/free在你的榜样。

换句话说,在一般的情况下的存储器块由分配new[]具有在实际的数据的前面的两组额外的字节:以字节为单位的块的大小(通过引入malloc )和元素计数(通过引入new[] 第二个是可选的,因为你的榜样示范。 第一个是通常总是存在的,因为它无条件地分配malloc 。 即你malloc的通话将物理分配超过20 ,即使你只请求字节20 。 这些额外的字节将被使用malloc存储字节的块大小。

后者发生在你的例子也是如此。 你根本看不到它,因为它里面发生malloc



Answer 2:

如果编译器不需要调用析构函数,它并不需要记住多少析构函数调用。 如果你有一个需要自毁,就像一个数据成员,你不会看到这种行为std::string ,因为编译器将总是需要进行破坏。



文章来源: Operator new[] does not receive extra bytes