7

我有这样的代码

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

在这种情况下,我收到sizein operator new 重载的值作为我想要的 20 个字节(sizeof(int) * 5)。但是如果我取消注释析构函数,我会得到size24 个字节。是的,我现在这些额外的字节用于存储分配内存的大小,等于sizeof(size_t). 我不明白为什么只有当我明确地实现析构函数时才能得到它们。如果我不这样做,编译器应该做同样的事情还是我错过了什么?

我已经在 MSVS 2010 和 2012 上尝试过。为 Win32 编译。

4

2 回答 2

7

"Extra bytes" requested by new[] from operator new[] are not used to "store the size of allocated memory", as you seem to believe. They are used to store the number of elements in the array, so that the delete[] will know how many destructors to call. In your example destructors are trivial. There's no need to call them. So, there's no need to allocate these extra bytes and store the element count.

The "size of allocated memory" (i.e. the size of the block in bytes) is a completely different story. It is stored and retrieved independently by a lower-level allocator - the malloc/free in your example.

In other words, in general case a memory block allocated by new[] has two sets of extra bytes in front of the actual data: the block size in bytes (introduced by malloc) and the element count (introduced by new[]). The second one is optional, as your example demonstrates. The first one is typically always present, as it is unconditionally allocated by malloc. I.e. your malloc call will physically allocate more than 20 bytes even if you request only 20. These extra bytes will be used by malloc to store the block size in bytes.

The latter happens in your example as well. You simply don't see it since it happens inside malloc.

于 2012-12-06T15:13:29.477 回答
6

如果编译器不需要调用析构函数,它就不需要记住要调用多少个析构函数。如果您有一个需要破坏的数据成员,例如 ,您将不会观察到这种行为std::string,因为编译器总是需要破坏它。

于 2012-12-06T15:11:47.703 回答