En muchos sistemas de microcontroladores, los compiladores y enlazadores asignan datos desde la parte inferior y / o superior de la RAM; la RAM no utilizada generalmente estará en un área contigua, y generalmente es posible convencer al enlazador para que haga que las direcciones de inicio y final de esa área estén disponibles para el programador (por ejemplo, se puede pedir al enlazador que coloque una variable de un byte como el la última cosa antes del área libre, y otra como la primera que sigue, las direcciones de esas variables delinearían el espacio libre).
Aunque muchos sistemas ofrecen una función malloc()
, es más complicado de lo necesario en muchos escenarios. Por ejemplo, si uno necesita asignar objetos en función de la información recibida en el tiempo de ejecución, pero los objetos siempre se liberarán en el orden inverso de asignación, uno simplemente puede mantener un puntero al "siguiente espacio disponible". Para asignar un objeto, copie ese puntero agregue el tamaño del nuevo objeto y devuelva el puntero copiado. Para liberar un objeto (y todo lo que se haya asignado después de él), simplemente establezca el puntero del "siguiente espacio disponible" al inicio de ese objeto.
Algunos escenarios son un poco más complejos de lo que se permitiría con ese enfoque, pero aún no necesitan un enfoque completo "malloc / free". Por ejemplo, en algunos escenarios, uno puede tener dos grupos de objetos que obedecen entre sí a la regla del último en el primero en salir, pero los objetos en un grupo pueden sobrevivir a los del otro. Para lidiar con esa situación, use un puntero de "siguiente espacio disponible" que comience en la parte inferior del espacio libre, y un puntero de "anterior espacio disponible" que comience en la parte superior. Asigna las cosas en el primer grupo como antes. Para aquellos en el segundo grupo, reste el tamaño del nuevo objeto del puntero de "espacio disponible anterior" y devuelva el resultado. Para liberar un objeto en el segundo grupo (y todos los objetos del segundo grupo asignados después de él), agregue el tamaño del objeto a su dirección y almacene el resultado en el puntero del "espacio disponible anterior".
Tenga en cuenta que malloc
y free
están diseñados para que sea posible liberar objetos en medio de la memoria, mientras que los objetos anteriores y posteriores siguen siendo válidos. Si bien esto puede ser útil a veces, también puede conducir a la fragmentación de la memoria. Si los objetos de uno no encajan con un modelo de último en entrar, primero, puede ser una buena idea hacer que los objetos sean reubicables. Por ejemplo, uno puede tener una cola de objetos de tamaño variable que se almacenan consecutivamente en la memoria siempre que haya espacio. Cuando la memoria se llena (o en algún momento conveniente antes de eso), uno copiaría el primer objeto que aún no se había leído al comienzo de la cola, el siguiente objeto que no se había leído inmediatamente después, etc. hasta que todos los objetos se habían copiado, consolidando el espacio libre que había al principio de la cola, hasta el final. Se debe tener cuidado al mover los datos para garantizar que los punteros a esos datos se actualicen en consecuencia, pero a menudo no es demasiado difícil. Mover la memoria puede requerir más ciclos de CPU que administrar áreas discontinuas de espacio libre, pero el comportamiento del enfoque de memoria en movimiento puede ser más predecible.