recoleccion programacion memoria liberar leaks basura avoid c++ winapi dll memory-management crt

c++ - memoria - recoleccion de basura en programacion



¿Una pérdida de memoria en la descarga de una DLL causa una fuga en el proceso de host? (6)

  1. La memoria utilizada por un proceso según el seguimiento del sistema operativo se aplica al proceso completo y no a una DLL.

  2. La memoria se le da al programa en pedazos por el sistema operativo, llamado montones

  3. Los gestores del montón (malloc / nuevo, etc.) dividen aún más los fragmentos y los distribuyen para solicitar el código.

  4. Solo cuando se asigna un nuevo montón, el sistema operativo detecta un aumento en la memoria.

  5. Cuando una DLL está vinculada estáticamente a la biblioteca de tiempo de ejecución de C (CRT), una copia privada de CRT con las funciones CRT que invoca el código DLL se compila y se coloca en el archivo binario de la DLL. Malloc también está incluido en esto.

  6. Esta copia privada de malloc se invocará siempre que el código presente dentro de la DLL enlazada estáticamente intente asignar memoria.

  7. En consecuencia, este malloc adquiere un montón privado visible solo para esta copia de malloc, y asigna la memoria solicitada por el código dentro de este montón privado.

  8. Cuando la DLL se descarga, descarga su pila privada, y esta fuga pasa desapercibida, ya que todo el montón vuelve al sistema operativo .

  9. Sin embargo, si el archivo DLL está vinculado dinámicamente, la memoria se asigna mediante una única versión compartida de malloc, global para todo el código que está vinculado en el modo compartido.

  10. La memoria asignada por este malloc global, sale de un montón que también es el montón utilizado para todos los demás códigos que están vinculados en el modo compartido dinámico aka y, por lo tanto, es común. Cualquier fuga de este montón se convierte en una fuga que afecta todo el proceso.

Editar - Se agregaron descripciones del escenario de enlace.

Considera este caso:

dll = LoadDLL() dll->do() ... void do() { char *a = malloc(1024); } ... UnloadDLL(dll);

En este punto, ¿el 1k asignado en la llamada a malloc () estará disponible para el proceso de host nuevamente? El DLL está enlazando estáticamente al CRT.


De los posibles errores de MSDN que pasan objetos CRT a través de los límites DLL

Cada copia de la biblioteca CRT tiene un estado separado y distinto. Como tal, los objetos CRT como los identificadores de archivo, las variables de entorno y las configuraciones regionales solo son válidos para la copia del CRT donde se asignan o establecen estos objetos. Cuando un archivo DLL y sus usuarios utilizan diferentes copias de la biblioteca CRT, no puede pasar estos objetos CRT a través del límite de DLL y esperar que se recojan correctamente en el otro lado.

Además, dado que cada copia de la biblioteca CRT tiene su propio administrador de montón, asignar memoria en una biblioteca CRT y pasar el puntero a través de un límite de DLL para ser liberado por una copia diferente de la biblioteca CRT es una causa potencial de corrupción del montón.

Espero que esto ayude.


No puedes decir. Esto depende de la implementación de su CRT estático y dinámico. Incluso puede depender del tamaño de la asignación, ya que hay CRT que envían grandes asignaciones al sistema operativo, pero implementan su propio montón para pequeñas asignaciones.

El problema con un CRT que se filtra es, por supuesto, que se filtra. El problema con un CRT que no tiene fugas es que el ejecutable podría razonablemente esperar usar la memoria, ya que la memoria malloc''ed debe seguir siendo utilizable hasta que se llame a free.


No, no tienes fugas.

Si mezcla modelos dll (estáticos, dinámicos), puede terminar con un error de memoria si asigna memoria en un dll, que libera en uno diferente (o liberado en el exe)

Esto significa que el montón creado por el CRT estáticamente enlazado no es el mismo montón que el CRT de un dll diferente.

Si se hubiera vinculado con la versión dinámica de la CRT, entonces tendría una fuga ya que la pila se comparte entre todas las CRT enlazadas dinámicamente. Significa que siempre debe diseñar sus aplicaciones para usar los CRT dinámicos, o asegurarse de que nunca administre la memoria a través de un límite dll (es decir, si asigna memoria en un dll, siempre proporcione una rutina para liberarla en el mismo dll)


Uno podría hacer una prueba y ver si hay pérdidas de memoria. Ejecuta una prueba simple 30 veces asignando 1 MB cada vez. Deberías resolver eso bastante rápido.

Una cosa es segura. Si asignó memoria en el archivo DLL también debería liberar esa memoria allí (en el archivo DLL).

Por ejemplo, debería tener algo como esto (pseudocódigo simple pero intuitivo):

dll = DllLoad(); ptr = dll->alloc(); dll->free(ptr); DllUnload(dll);

Esto debe hacerse porque el archivo DLL tiene un montón diferente que el proceso original (que carga el dll).


En realidad, la respuesta marcada es incorrecta. Que hay una fuga Si bien es técnicamente posible que cada dll implemente su propio montón y lo libere al apagarlo, la mayoría de los montones de "tiempo de ejecución", estáticos o dinámicos, son envoltorios alrededor de la API del montón de procesos de Win32.

A menos que se haya tenido especial cuidado de garantizar que este no sea el caso, el dll perderá la asignación por ciclo de carga, carga y descarga.