オレオレアロケータ
newとかmalloc()した領域をひっくるめて保持しておいて、リクエストに応じて区別無くfreeでブチ殺すとか、何か使い道ないかなあ(まだゆーか)
404 Not Found
釈迦に説法かもしれませんが、
ありますよ、オレオレアロケータ!!(ドラえもんの声で)
と、newは引数を使ってオーバーロードできるのでクラスに対してnew operatorとdelete operatorを制御することで、
一気にメモリを確保して、一気に解放できます。
static void* operator new( std::size_t size, CAllocator& allocator ) {
と宣言して、自前のアロケータを指定してやればOKでございます。
書き方によっては暗黙で使っても良いです。使う人はそれを知ってないと駄目ですが。
for文で回しているところは、こういう感じに一気にとるならnew []でいいので、
そうではなく、ある個数まで限定された状況でどこかのタイミングで個々にnewされるもの、と考えてください。
ゲームのミサイルとかでもよござんす。
で、deleteは何もしてません。destructorを呼び出すだけです。
このハイスピードnew(ってか単にメモリを切り売りしているだけなので)は逐一のメモリの解放を許しません。
というか、できません(笑
で、あるタイミングでアロケータがメモリを一気に解放します。
ゲームとかある期間内で有数個のオブジェクトが必要でかつまたnewやdeleteのコストを許容できないときに、
使えますよん。
#include <stdio.h> #include <stdlib.h> class CAllocator { public: CAllocator(int size) { printf("init\n"); _buffer = (char*)calloc(1,size); _cursor = 0; _count = 0; } ~CAllocator() { free(_buffer); } void* alloc( std::size_t size ){ int cursor = _cursor; _cursor+=size; _count++; return (void*)(_buffer+cursor); } void reset() { _cursor = 0; _count = 0; } void info() { printf("[COUNT:%d,CURSOR:%d]\n",_count,_cursor); } private: char* _buffer; int _cursor; int _count; }; class CHoge { public: CHoge() { printf("constructor\n"); _a = _b = 100; } ~CHoge() { printf("destructor\n"); } static void* operator new( std::size_t size, CAllocator& allocator ) { printf("new\n"); return allocator.alloc(size); } static void operator delete( void* p ){ printf("delete\n"); } private: int _a; int _b; }; int main(int argc, char *argv[]) { CAllocator allocator(sizeof(CHoge)*100); CHoge* hoges[100]; for (int i = 0; i < 100; i++ ) { hoges[i] = new (allocator) CHoge(); } allocator.info(); for (int i = 0; i < 100; i++ ) { delete hoges[i]; } return 0; }
infoでは、
[COUNT:100,CURSOR:800]
と表示されます。
いかにdeleteしても領域は復活しないので、
有数個でありながら、
消滅したものをリサイクルするには「現在あるものもすべて消滅させなければならない」ので、
ミサイルなどに使うには、「その面で出現するミサイルの最大個数」とかで確保する手があります。
無限にでるものは使いにくいです。
どこかですべてが消滅するタイミングが必要なので。(逆にそれがあればリサイクル可能=敵がでない期間とかでもよいわけで)
と、適当を言ってみます。(真面目なSTGつくったことないので)
こんなことをしなくてもプールして再利用でいいんじゃない、っていうのは秘密です。
追記:デストラクタでfreeしなければならないものをdeleteしてました!orz
すみません。odzさんの指摘で修正。