Created
January 28, 2013 15:58
-
-
Save hadashiA/4656672 to your computer and use it in GitHub Desktop.
可変長のメモリアロケータ (再利用は未サポート…)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <cstddef> | |
class MemoryChunk { | |
public: | |
MemoryChunk(MemoryChunk *next_chunk, size_t req_size) | |
: next_(next_chunk), | |
chunk_size_(req_size > DEFAULT_CHUNK_SIZE ? req_size : DEFAULT_CHUNK_SIZE), | |
bytes_already_allocated_(0) { | |
allocated_ = malloc(chunk_size_); | |
} | |
~MemoryChunk() { | |
free(allocated_); | |
} | |
void *Alloc(size_t req_size) { | |
size_t addr = static_cast<size_t>(reinterpret_cast<size_t>(allocated_) + bytes_already_allocated_); | |
bytes_already_allocated_ += req_size; | |
return reinterpret_cast<void *>(addr); | |
} | |
void Free(void *some_element) { | |
} | |
MemoryChunk *next() { | |
return next_; | |
} | |
size_t space_available() { | |
return chunk_size_ - bytes_already_allocated_; | |
} | |
// 単一のメモリチャンクのデフォルトサイズ | |
enum { DEFAULT_CHUNK_SIZE = 4096 }; | |
private: | |
MemoryChunk *next_; | |
void *allocated_; | |
size_t chunk_size_; // 単一メモリチャンクのサイズ | |
size_t bytes_already_allocated_; // 現在のメモリチャンクに既に確保されているバイト | |
}; | |
class ByteMemoryPool { | |
public: | |
ByteMemoryPool(size_t init_size = MemoryChunk::DEFAULT_CHUNK_SIZE) { | |
ExpandStorage(init_size); | |
} | |
~ByteMemoryPool() { | |
MemoryChunk *chunk = chunk_; | |
while (chunk_) { | |
chunk_ = chunk->next(); | |
delete chunk; | |
chunk = chunk_; | |
} | |
} | |
// プライベートプールからメモリを確保する | |
void *Alloc(size_t req_size) { | |
if (chunk_->space_available() < req_size) { | |
ExpandStorage(req_size); | |
} | |
return chunk_->Alloc(req_size); | |
} | |
// プールからこれまでに確保したメモリを解放する | |
void Free(void *doomed) { | |
chunk_->Free(doomed); | |
} | |
private: | |
void ExpandStorage(size_t req_size) { | |
chunk_ = new MemoryChunk(chunk_, req_size); | |
} | |
MemoryChunk *chunk_; | |
}; | |
class Rational { | |
public: | |
Rational(int n = 0, int d = 1) : n_(n), d_(d) {}; | |
void *operator new(size_t size) { | |
return __pool->Alloc(size); | |
} | |
void operator delete(void *doomed, size_t size) { | |
__pool->Free(doomed); | |
} | |
static void NewMemPool() { __pool = new ByteMemoryPool; } | |
static void PurgeMemPool() { delete __pool; } | |
// int n() { return n_; } | |
// int d() { return d_; } | |
private: | |
static ByteMemoryPool *__pool; | |
int n_; // 分子 | |
int d_; // 分母 | |
}; | |
ByteMemoryPool *Rational::__pool = NULL; | |
int main(int argc, char **argv) { | |
Rational *array[1000]; | |
Rational::NewMemPool(); | |
for (int j = 0; j < 500; ++j) { | |
for (int i = 0; i < 1000; ++i) { | |
array[i] = new Rational(i); | |
} | |
for (int i = 0; i < 1000; ++i) { | |
delete array[i]; | |
} | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment