Ви розробляєте нову езотеричну мову програмування і однією з особливостей, яку ви вирішили додати, є динамічний розподільник пам'яті. Ваша мова визначає спеціальний віртуальний адресний простір для програмного простору користувача. Це окремо від адресного простору, який використовується розподільником пам'яті для будь-якого внутрішнього стану.
Щоб зменшити витрати на розповсюдження вашої реалізації, розмір коду повинен бути якомога меншим.
Інтерфейс
Ви повинні надати три функції: ініціалізація, розподілення та розміщення.
Ініціалізація
Ця функція приймає єдиний натуральний параметр N. Це означає, що програма користувача має Nв своєму адресному просторі N-1байти, з яких є байти, з яких можна виділити пам'ять. Адреса 0зарезервована для "null".
Гарантується, що ця функція буде викликана рівно один раз перед будь-якими викликами розподілення / угоди.
Зауважте, що цій функції не потрібно виділяти будь-яку фізичну пам'ять для віртуального адресного простору програми користувача; ви в основному створюєте "зовнішній вигляд" порожнього розподільника пам'яті.
Виділити
Функція розподілу повинна приймати запит на кількість байтів пам'яті, яку потрібно виділити. Вхід гарантовано позитивний.
Ваша функція повинна повернути цілу адресу до початку виділеного блоку або 0позначати, що не існує суміжного блоку потрібного розміру. Якщо суміжний блок доступного розміру є в будь-якому місці адресного простору, його потрібно виділити!
Ви повинні переконатися, що два виділені блоки не перетинаються.
Розподіліть
Функція ділокації повинна приймати адресу початку виділеного блоку, і необов'язково може також приймати розмір заданого блоку.
Пам'ять, яка була розміщена, знову доступна для розподілу. Передбачається, що вхідна адреса є дійсною адресою.
Приклад реалізації 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