Stai progettando un nuovo linguaggio di programmazione esoterico e una caratteristica che hai deciso di aggiungere è un allocatore di memoria dinamica. La tua lingua specifica uno spazio di indirizzi virtuale dedicato speciale per lo spazio del programma dell'utente. Questo è separato dallo spazio degli indirizzi utilizzato dall'allocatore di memoria per qualsiasi stato interno.
Per aiutare a ridurre i costi di distribuzione dell'implementazione, la dimensione del codice deve essere il più piccola possibile.
Interfaccia
È necessario fornire tre funzioni: inizializzazione, allocazione e deallocazione.
Inizializzazione
Questa funzione accetta un singolo parametro intero positivo N. Ciò significa che il programma di un utente ha Nbyte nel suo spazio di indirizzi da cui ci sono N-1byte da cui allocare memoria. L'indirizzo 0è riservato per "null".
È garantito che questa funzione verrà chiamata esattamente una volta prima di qualsiasi chiamata di allocazione / deallocazione.
Si noti che questa funzione non ha bisogno di allocare memoria fisica per lo spazio degli indirizzi virtuali del programma utente; stai fondamentalmente creando il "look and feel" di un allocatore di memoria vuoto.
assegnare
La funzione di allocazione deve accettare una richiesta del numero di byte di memoria da allocare. L'input è garantito per essere positivo.
La funzione deve restituire un indirizzo intero all'inizio del blocco allocato o 0per indicare che non è disponibile alcun blocco contiguo della dimensione richiesta. Se un blocco contiguo delle dimensioni disponibili è disponibile in qualsiasi punto dello spazio degli indirizzi, è necessario allocare!
È necessario assicurarsi che non si sovrappongano due blocchi allocati.
Dealloca
La funzione deallocazione deve prendere un indirizzo dell'inizio di un blocco allocato e, facoltativamente, può anche prendere la dimensione del blocco dato.
La memoria che è stata deallocata è di nuovo disponibile per l'allocazione. Si presume che l'indirizzo di input sia un indirizzo valido.
Esempio di implementazione di Python
Si noti che è possibile scegliere qualsiasi metodo per tenere traccia dello stato interno; in questo esempio l'istanza di classe ne tiene traccia.
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]
punteggio
Questo è il codice golf; vince il codice più breve in byte. Non devi preoccuparti di rimanere senza memoria per qualsiasi stato interno richiesto dal tuo allocatore.
Si applicano fori ad anello standard.
Classifica
To help reduce the cost of distributing your implementation the size of the code must be as small as possibleo potrebbe essere efficiente (piccolo ed efficiente non è lo stesso) possibile? : D