#include /* * Memory Pool * * Obiekty tej klasy powinny być globalne * * Zakładamy że mamy obiekty dzieci Rakieta, Granat i rodzica Obiekt * Wiemy ze max(sizeof(Rakieta), sizeof(Granat)) == 32 * W tej chwili możemy użyć CMemoryPool * * Jak używać? * CMemoryPool PociskMemoryPool(32, 1000); // Gdzieś dostępną globalnie * * I dwie metody * * template * inline T* NewObject(argumenty konstruktora) * { * return new (PociskMemoryPool.Alloc()) T(argumenty konstuktora); * } * * Jeśli Rakieta i Granat mają różne konstuktory tworzymy dwie/więcej funkcji * * Destrukcja obiektów wygląda tak * * inline void DeleteObject(Pocisk* bullet) * { * bullet->~Pocisk(); * BulletsMemoryPool.Free(bullet); * } */ typedef size_t msize; class CMemoryPool { private: void* FreeChunk; // Wolny kawałek pamięci void* Pool; // Adres pierwszego kawałka pamięci const msize ChunkSize; // Rozmiar pojedyńczego kawałka const msize ChunkCount; // Liczba kawałków public: msize GetChunkSize() const { return ChunkSize; } msize GetChunkCount() const { return ChunkCount; } msize GetPoolSize() const { return ChunkSize * ChunkCount; } CMemoryPool(msize chunksize, msize chunkcount) : ChunkSize(chunksize), ChunkCount(chunkcount) { assert(chunksize >= 4); size_t poolsize = chunksize * chunkcount; Pool = malloc(poolsize); assert(Pool); FreeChunk = Pool; msize offset = (msize)Pool + PoolSize - ChunkSize; msize rawlastptr = 0; while ((void*)offset != Pool) { *((msize*)offset) = rawlastptr; rawlastptr = offset; offset -= ChunkSize; } *((msize*)Pool) = rawlastptr; } ~CMemoryPool() { free(Pool); } public: // Zwraca wskaznik do zaalokowanej pamięci void* Alloc() { if (FreeChunk == 0) { assert(!"Out of memory"); return 0; } void* result = FreeChunk; FreeChunk = (void*)*((msize*)FreeChunk); return result; } // Zwalnia pamięć void Free(void* ptr) { *((msize*)ptr) = (msize)FreeChunk; FreeChunk = ptr; } };