新しい難解なプログラミング言語を設計していて、追加することに決めた機能の1つが動的メモリアロケーターです。あなたの言語は、ユーザーのプログラム空間に特別な専用仮想アドレス空間を指定します。これは、メモリアロケーターが内部状態に使用するアドレス空間とは別のものです。
実装の配布コストを削減するには、コードのサイズをできるだけ小さくする必要があります。
インターフェース
初期化、割り当て、および割り当て解除の3つの機能を提供する必要があります。
初期化
この関数は、単一の正の整数パラメータを取りますN。これは、ユーザーのプログラムのNアドレス空間にN-1バイトがあり、そこからメモリを割り当てるバイトがあることを意味します。アドレス0は「null」用に予約されています。
この関数は、割り当て/割り当て解除の呼び出しの前に1回だけ呼び出されることが保証されています。
この関数は、ユーザープログラムの仮想アドレス空間に物理メモリを割り当てる必要がないことに注意してください。基本的に、空のメモリアロケータの「ルックアンドフィール」を作成しています。
割り当てる
割り当て関数は、割り当てるメモリのバイト数の要求を受け取る必要があります。入力は正であることが保証されています。
関数は、割り当てられたブロックの先頭に整数アドレスを返すか0、要求されたサイズの連続するブロックが利用できないことを示す必要があります。使用可能なサイズの連続したブロックがアドレス空間のどこでも使用できる場合、割り当てる必要があります
割り当てられた2つのブロックが重複しないようにする必要があります。
割り当て解除
deallocate関数は、割り当てられたブロックの開始アドレスを取得する必要があり、オプションで特定のブロックのサイズを取得することもできます。
割り当て解除されたメモリは再び割り当てに使用できます。入力住所は有効な住所であると想定されます。
Python実装の例
内部状態を追跡するための任意の方法を選択できることに注意してください。この例では、クラスインスタンスがそれを追跡します。
class myallocator:
def __init__(self, N):
# address 0 is special, it's always reserved for null
# address N is technically outside the address space, so use that as a
# marker
self.addrs = [0, N]
self.sizes = [1, 0]
def allocate(self, size):
for i,a1,s1,a2 in zip(range(len(self.addrs)),
self.addrs[:-1], self.sizes[:-1],
self.addrs[1:]):
if(a2 - (a1+s1) >= size):
# enough available space, take it
self.addrs.insert(i+1, a1+s1)
self.sizes.insert(i+1, size)
return a1+s1
# no contiguous spaces large enough to take our block
return 0
def deallocate(self, addr, size=0):
# your implementation has the option of taking in a size parameter
# in this implementation it's not used
i = self.addrs.index(addr)
del self.addrs[i]
del self.sizes[i]
得点
これはコードゴルフです。バイト単位の最短コードが優先されます。アロケータに必要な内部状態のためにメモリが不足することを心配する必要はありません。
標準のループ穴が適用されます。
リーダーボード
To help reduce the cost of distributing your implementation the size of the code must be as small as possibleまたは、可能な限り効率的である可能性があります(小さくても効率的でもありません)。:D