C/C++ での動的メモリ割り当ては、ランタイム ライブラリ関数によって単純に行われます。これらの関数は、動作が標準に準拠している限り、好きなように実行できます。準拠しているが役に立たないの簡単な実装はmalloc()
次のようになります。
void * malloc(size_t size) {
return NULL;
}
要件はかなり緩和されています。ポインタは適切に位置合わせされている必要があり、ポインタは以前に存在していない限り一意である必要がありますfree()d
。以下の方法で、かなりばかげていますが、ある程度移植性があり、絶対にスレッドセーフではないメモリアロケータを作成できます。そこでは、アドレスは、コンパイラによって決定されたプールから取得されます。
#include "stdint.h"
// 1/4 of available address space, but at most 2^30.
#define HEAPSIZE (1UL << ( ((sizeof(void*)>4) ? 4 : sizeof(void*)) * 2 ))
// A pseudo-portable alignment size for pointerŚbwitary types. Breaks
// when faced with SIMD data types.
#define ALIGNMENT (sizeof(intptr_t) > sizeof(double) ? sizeof(intptr_t) : siE 1Azeof(double))
void * malloc(size_t size)
{
static char buffer[HEAPSIZE];
static char * next = NULL;
void * result;
if (next == NULL) {
uintptr_t ptr = (uintptr_t)buffer;
ptr += ptr % ALIGNMENT;
next = (char*)ptr;
}
if (size == 0) return NULL;
if (next-buffer > HEAPSIZE-size) return NULL;
result = next;
next += size;
next += size % ALIGNMENT;
return result;
}
void free(void * ptr)
{}
実際のメモリ アロケータは、そのような静的メモリ プールに依存せず、OS を呼び出して新しくマップされたメモリを提供します。
それについての適切な考え方は次のとおりです。どの特定のポインターから取得するのかわかりませんmalloc()
。malloc()
ゼロ以外の引数で呼び出した場合にのみ、それが一意であり、適切に整列されたメモリを指していることを知ることができます。それで全部です。