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

この場合、必要にsize応じて、演算子の新しいオーバーロードの値を20バイトとして受け取ります(sizeof(int) * 5)。しかし、デストラクタのコメントを外すと、size24バイトになります。ええ、私は今、これらの余分なバイトが割り当てられたメモリのサイズを格納するために使用され、に等しいですsizeof(size_t)。デストラクタを明示的に実装した場合にのみ、なぜそれらを取得するのか理解できません。私がそれをしなければ、コンパイラはまったく同じことをするべきですか、それとも私は何かを逃していますか?

私はMSVS2010と2012でそれを試しました。Win32用にコンパイルされています。

4

2 に答える 2

7

new[]から要求された「余分なバイト」はoperator new[]、あなたが信じているように、「割り当てられたメモリのサイズを格納する」ために使用されません。これらは、配列内の要素の数delete[]を格納するために使用されるため、は呼び出すデストラクタの数を知ることができます。あなたの例では、デストラクタは取るに足らないものです。それらを呼び出す必要はありません。したがって、これらの余分なバイトを割り当てて要素数を格納する必要はありません。

「割り当てられたメモリのサイズ」(つまり、バイト単位のブロックのサイズ)はまったく別の話です。これは、下位レベルのアロケータ(このmalloc/free例では)によって個別に保存および取得されます。

言い換えると、一般的な場合、によって割り当てられたメモリブロックにnew[]は、実際のデータの前に2セットの追加バイトがあります。バイト単位のブロックサイズ(によって導入されるmalloc)と要素数(によって導入されるnew[])です。あなたの例が示すように、2番目のものはオプションです。最初のものは、によって無条件に割り当てられるため、通常は常に存在しmallocます。つまり、要求した場合でも、malloc呼び出しは物理的にバイト以上を割り当てます。これらの余分なバイトは、ブロックサイズをバイト単位で格納するために使用されます。2020malloc

後者はあなたの例でも起こります。それは内部で発生するため、単に表示されませんmalloc

于 2012-12-06T15:13:29.477 に答える
6

コンパイラがデストラクタを呼び出す必要がない場合は、呼び出すデストラクタの数を覚えておく必要はありません。std::stringコンパイラが常にデータを破棄する必要があるため、のように破棄が必要なデータメンバーがある場合、この動作は観察されません。

于 2012-12-06T15:11:47.703 に答える