読者です 読者をやめる 読者になる 読者になる

オレオレアロケータ

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さんの指摘で修正。