Skip to content

Instantly share code, notes, and snippets.

@hadashiA
Created January 28, 2013 15:58
Show Gist options
  • Save hadashiA/4656672 to your computer and use it in GitHub Desktop.
Save hadashiA/4656672 to your computer and use it in GitHub Desktop.
可変長のメモリアロケータ (再利用は未サポート…)
#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