Esa es en realidad una pregunta bastante vaga, y esa es probablemente la razón por la que te confundiste. ¿Quiere decir, dada una implementación malloc existente, cómo trataría de desarrollar una forma más eficiente de liberar la memoria subyacente? ¿O esperaba que comenzaras a discutir diferentes tipos de implementaciones de malloc y sus beneficios y problemas? ¿Esperaba que supiera cómo funciona la memoria virtual en la arquitectura x86?
Además, por más eficiente, ¿quiere decir más eficiente en el uso del espacio o más eficiente en el tiempo? ¿Libre() tiene que ser determinista? ¿Tiene que devolver la mayor cantidad posible de memoria al sistema operativo porque se encuentra en un entorno con poca memoria y tareas múltiples? ¿Cuál es nuestro criterio aquí?
Es difícil decir por dónde empezar con una pregunta vaga como esa, aparte de comenzar a hacer sus propias preguntas para obtener una aclaración. Después de todo, para diseñar su propia función gratuita, primero debe saber cómo se implementa malloc. Entonces, lo más probable es que la pregunta era si sabías o no sobre cómo se puede implementar Malloc.
Si no está familiarizado con las funciones internas de la administración de la memoria, la forma más fácil de comenzar con la comprensión de cómo se implementa malloc es escribir primero la suya propia.
Consulte this IBM DeveloperWorks article called "Inside Memory Management" para empezar.
Pero antes de que pueda escribir su propio malloc/free, primero necesita memoria para asignar/libre. Desafortunadamente, en un SO de modo protegido, no puede direccionar directamente la memoria en la máquina. Entonces, ¿cómo lo consigue?
Solicítelo al sistema operativo. Con las funciones de memoria virtual del x86, cualquier parte de la memoria RAM o de intercambio se puede asignar a una dirección de memoria por el sistema operativo. Lo que su programa ve como memoria podría estar físicamente fragmentado en todo el sistema, pero gracias al administrador de memoria virtual del núcleo, todo parece igual.
El kernel generalmente proporciona llamadas al sistema que le permiten asignar memoria adicional para su proceso. En los sistemas operativos UNIX más antiguos, esto generalmente era brk/sbrk para hacer crecer la memoria dinámica en el borde de su proceso o reducirla, pero muchos sistemas también proporcionan mmap/munmap para simplemente mapear un gran bloque de memoria dinámica. Es solo una vez que tener acceso a un gran bloque de memoria de aspecto contiguo que necesita malloc/free para administrarlo.
Una vez que su proceso tiene algo de memoria de montón disponible, se trata de dividirlo en fragmentos, con cada fragmento conteniendo su propia meta información sobre su tamaño y posición y si está asignado o no, y luego administrar esos fragmentos. Una simple lista de estructuras, cada una con algunos campos para metainformación y una gran cantidad de bytes, podría funcionar, en cuyo caso Malloc debe ejecutar la lista hasta encontrar un trozo no asignado lo suficientemente grande (o trozos que pueda combinar), y luego mapea con más memoria si no puede encontrar un trozo suficientemente grande. Una vez que encuentras un trozo, simplemente devuelves un puntero a los datos. free() puede usar ese puntero para retroceder algunos bytes a los campos de miembros que existen en la estructura, que luego puede modificar (es decir, marcar chunk.allocated = false;).Si hay suficientes fragmentos no asignados al final de su lista, puede incluso eliminarlos de la lista y desasignar o reducir esa memoria fuera del montón del proceso.
Sin embargo, es un método realmente simple para implementar malloc. Como se puede imaginar, hay muchas maneras posibles de dividir su memoria en fragmentos y luego administrar esos fragmentos. Hay tantas formas como estructuras de datos y algoritmos. Todos están diseñados para diferentes propósitos, como limitar la fragmentación debido a trozos pequeños asignados mezclados con trozos pequeños no asignados, o asegurar que malloc y libre corren rápido (o a veces incluso más lentamente, pero de forma más lenta). Hay dlmalloc, ptmalloc, jemalloc, Hoard's malloc, y muchos más, y muchos de ellos son bastante pequeños y concisos, así que no temas leerlos. Si mal no recuerdo, "The C Programming Language" de Kernighan y Ritchie incluso usa una implementación simple de malloc como uno de sus ejemplos.
También necesitaría su propio 'malloc' para que esto sea útil, ¿no? – pmr
Dado que la implementación de 'free' no está especificada por el estándar, no veo cómo alguien podría responder 2. –
No se puede dar una respuesta absoluta, pero crea un buen punto para hablar, que probablemente fue el ¡punto! Estoy de acuerdo en que necesitarías tu propio Malloc, de lo contrario no hay posibilidad de reutilizar la memoria. De hecho, señalar tales cosas "obvias" es probablemente lo que él/ella fue seguido por una discusión más profunda sobre cómo escribir un sistema de asignación de memoria dinámico eficiente (velocidad vs memoria, etc.). Recuerde: un entrevistador no está tratando de engañarlo, sino que está tratando de ver cómo aborda los problemas y lo que sabe. Piense en voz alta y pida una aclaración. ¡Muéstrales lo que sabes! – noelicus