0

カスタムスタックアロケータでは、を使用してプログラムの起動時に大量のメモリを割り当てmalloc()、次にプログラムのシャットダウン時にfree()すべてのメモリを割り当てます。

つまり、基本的には次のようになります。

//start up
m_pInitialPosition = malloc(STACK_SIZE);

//shutdown
free(m_pInitilaPosition);

新しいオブジェクトを作成する必要があるときは、次のように呼び出しますallocateNew()

 Actor* pActor = getStackAllocator().allocateNew<Actor>();
 *pActor = Actor();

これはallocateNew()次のようになります。

template <class T>
T* allocateNew()
{
   //allocate returns void*
   return new (allocate(sizeof(T), __alignof(T))) T;
}

次のコマンドを呼び出すと、問題が発生します(_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse例外)。

delete pActor;

その行を削除するだけで問題は解消free()され、スタックアロケータを呼び出しているためメモリリークは発生しませんが、Actorのデストラクタは呼び出されません...

では、デストラクタが確実に呼び出されるようにするには、何を変更できますか?

4

2 に答える 2

3

を呼び出すとdelete、が指すオブジェクトpActorが破棄され、メモリはデフォルトのデロケータ(free()の場合もあります)を使用して解放されます。オブジェクトはアロケータによって割り当てられているため、機能しません。

次のようなオブジェクトの削除を処理する新しいメソッドを定義します。

template<class T> void deleteObject(T *obj) {
   if (obj!=nullptr) {  // do nothing is obj is null
      obj->~T(); // call the object's destructor
      deallocate(obj);  // your method to handle deallocation in your 'memory pool'
   }
}

そして、削除を次のように置き換えます。

 getStackAllocator().deleteObject(pActor);

この記事では、カスタムメモリアロケータの作成方法について説明します:http://bitsquid.blogspot.fr/2010/09/custom-memory-allocation-in-c.html


さらに、私はあなたのコードに疑問を持っています。これらの行は何をすることになっていますか?

Actor* pActor = getStackAllocator().allocateNew<Actor>();
*pActor = Actor();

1-locateNew()が割り当てとデフォルトの構築の両方を実行する場合、それは問題ありませんが、2行目は役に立ちませんか?2-locateNew()がオブジェクトを初期化せずに代入のみを実行する場合、2行目は間違っています。初期化されていないオブジェクトに対して代入演算子を呼び出します。

于 2012-06-09T15:41:39.187 に答える
2

delete pActor配置を適切に補完するものではありませんnew。オブジェクトの構築を「元に戻す」にはnew (allocate(sizeof(T), __alignof(T))) T、デストラクタのみを呼び出す必要がありますdelete。これを使用しないでください。これにより、次の場所へのポインタでメモリの割り当てが解除されます。pActor

例えば

pActor->~Actor();

おそらくこれをスタックアロケータクラスのメンバー関数でラップして、クライアントがオブジェクトの割り当てを解除する方法を魔法のように知る必要がなく、アロケータの実装を更新する自由を与える必要があります。

例えば

template <class T>
void deallocate(T* t)
{
    t->~T();
}
于 2012-06-09T15:42:30.303 に答える