В дополнение к основным проблемам, указанным Недом Батчелдером , гораздо более тонкая проблема заключается в том, что распределитель должен возвращать адрес, который правильно выровнен для любого объекта, который выделяется. На некоторых платформах (x86) это может не иметь значения, за исключением проблем с производительностью, но на многих платформах это полный провал.
Мне также пришлось выполнить (char*)
приведение, чтобы выполнить stack
арифметику указателя (вы не можете выполнять арифметику указателя на типах void*
).
И вы должны ставить скобки вокруг выражения в макросе MAX_MEMORY
. Я не думаю, что есть какие-либо проблемы с приоритетом, с которыми вы бы столкнулись без них, так как все операторы с высоким приоритетом, кроме умножения, в любом случае не были бы правильным синтаксисом. С макросами это всегда лучше, чем потом сожалеть. (Существует по крайней мере одно исключение, когда оператор []
может связываться только с 2
, а не с целым выражением MAX_MEMORY
, но было бы очень странно видеть MAX_MEMORY[arrayname]
, даже если он синтаксически действителен).
На самом деле, я бы сделал это перечислением.
Вероятно, вы можете сохранить распределитель простым, возвращая блок памяти, правильно выровненный для любого базового типа данных в системе (возможно, 8-байтовое выравнивание):
/* Note: the following is untested */
/* it includes changes suggested by Batchelder */
#include <stdio.h>
#include <unistd.h>
enum {
kMaxMemory = 1024 * 1024 * 2, /* 2MB of memory */
kAlignment = 8
};
void *stack = NULL; /* pointer to available stack */
void * memoryAlloc( size_t size) {
void *pointer;
size = (size + kAlignment - 1) & ~(kAlignment - 1); /* round size up so allocations stay aligned */
if (stack == NULL)
stack = sbrk(kMaxMemory); /* give us system memory */
pointer = stack; /* we always have space :) */
stack = (char*) stack + size; /* move in stack forward as space allocated */
return pointer;
}