0

これは私のシナリオです。新しいものをオーバーロードしてグローバルに削除しようとしています。allocator.h というファイルにアロケーター クラスを記述しました。そして、私が達成しようとしているのは、ファイルにこのヘッダー ファイルが含まれている場合、私のバージョンの new と delete を使用する必要があるということです。

したがって、ヘッダーファイル「allocator.h」で、2つの関数を宣言しました

extern void* operator new(std::size_t size);
extern void operator delete(void *p, std::size_t size);

私はすべてのアロケータを行うクラスを持っているのと同じヘッダファイル、

class SmallObjAllocator
{
    ...
};

このクラスを new 関数と delete 関数から呼び出したいのですが、クラスを静的にしたいので、次のようにしました。

template<unsigned dummy>
struct My_SmallObjectAllocatorImpl
{
    static SmallObjAllocator myAlloc;
};

template<unsigned dummy>
SmallObjAllocator My_SmallObjectAllocatorImpl<dummy>::myAlloc(DEFAULT_CHUNK_SIZE, MAX_OBJ_SIZE);

typedef My_SmallObjectAllocatorImpl<0> My_SmallObjectAllocator;

cpp ファイルでは、次のようになります: allocator.cc

void* operator new(std::size_t size)
{

    std::cout << "using my new" << std::endl;

    if(size > MAX_OBJ_SIZE)
        return malloc(size);
    else
        return My_SmallObjectAllocator::myAlloc.allocate(size);
}

void operator delete(void *p, std::size_t size)
{
    if(size > MAX_OBJ_SIZE)
        free(p);
    else
        My_SmallObjectAllocator::myAlloc.deallocate(p, size);
}

問題は、静的オブジェクトである SmallObjAllocator クラスのコンストラクターを呼び出そうとしたときです。何らかの理由で、コンパイラはオーバーロードされた関数を初期化するときに new と呼んでいます。そのため、My_SmallObjectAllocator::myAlloc.deallocate(p, size); を使用しようとします。これは定義されていないため、プログラムがクラッシュします。

では、静的オブジェクトを定義するときにコンパイラが new を呼び出すのはなぜですか? どうすれば解決できますか?

4

1 に答える 1

2

operator new独自のものを提供する場合、ランタイム ライブラリのグローバルを使用することはできません。newしたがって、初期化であっても、実装に使用することはできませんnew。異なるソース ファイルで differentを使用operator newすることは、1 つの定義の規則に違反します。

コンストラクターnewからの呼び出しを削除するか、グローバルまたはローカルフラグによってアクティブ化される特別なケースを実装します。SmallObjAllocator::SmallObjAllocatorbool new_uninitializedstatic bool new_is_recursing

于 2010-05-06T10:16:43.880 に答える