Вы разрабатываете новый эзотерический язык программирования, и одну из функций, которую вы решили добавить, это динамический распределитель памяти. Ваш язык определяет специальное выделенное виртуальное адресное пространство для программного пространства пользователя. Это отдельно от адресного пространства, используемого распределителем памяти для любого внутреннего состояния.
Чтобы снизить стоимость распространения вашей реализации, размер кода должен быть как можно меньше.
Интерфейс
Вы должны предоставить три функции: инициализация, распределение и освобождение.
инициализация
Эта функция принимает один положительный целочисленный параметр N
. Это означает, что у программы пользователя есть N
байты в его адресном пространстве, из которого есть N-1
байты для выделения памяти. Адрес 0
зарезервирован для «ноль».
Гарантируется, что эта функция будет вызываться ровно один раз перед любыми вызовами выделения / удаления.
Обратите внимание, что этой функции не нужно выделять физическую память для виртуального адресного пространства программы пользователя; вы в основном создаете «внешний вид» полого распределителя памяти.
ассигновать
Функция allocate должна принять запрос количества байтов памяти для выделения. Вход гарантированно будет положительным.
Ваша функция должна возвратить целочисленный адрес в начало выделенного блока или 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]
счет
Это код гольф; выигрывает самый короткий код в байтах. Вам не нужно беспокоиться об исчерпании памяти для любого внутреннего состояния, требуемого вашим распределителем.
Применяются стандартные петлевые отверстия.
Leaderboard
To help reduce the cost of distributing your implementation the size of the code must be as small as possible
или это может быть эффективным (маленький и эффективный не то же самое), насколько это возможно? : D