2008-09-25 5 views

Respuesta

0

No, no tiene fugas.

Si mezcla modelos DLL (estática y dinámica), entonces usted puede terminar con un error de memoria si asigna memoria en un archivo DLL, que liberan en una diferente (o liberado en el exe)

Este 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 hubiera vinculado con la versión dinámica de la CRT, entonces tendría una fuga ya que la pila se comparte entre todos los CRT conectados dinámicamente. Significa que siempre debe diseñar sus aplicaciones para usar los CRT dinámicos o asegurarse de nunca administrar la memoria en un límite dll (es decir, si asigna memoria en un dll, siempre proporcione una rutina para liberarlo en el mismo dll)

+0

¡Gracias! ¿Podría explicar cómo/cuándo el CRT desasigna su almacenamiento de almacenamiento dinámico? ¿Se agrega esto como un tipo de código de salida dll predeterminado por el compilador/vinculador? – Viktor

+3

ADVERTENCIA: ¡Depende de la implementación! Un CRT puede simplemente proporcionar acceso al almacenamiento dinámico del sistema operativo para un proceso, en cuyo caso usted * puede * asignar en un archivo DLL y libre al exterior. – MSalters

+2

Se llamará a DllMain en la salida.Espero que los recuentos de referencia hasta que el dll esté completamente descargado, y luego elimine el montón. MSalters tiene razón, por ejemplo, puede asignar en cualquier lugar y liberar en cualquier lugar, pero si su aplicación se bloquea, se pierde la memoria que nada menos que un reinicio puede liberar (por ejemplo, Win3.1 montón global) – gbjbaanb

1

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, usted debe tener algo como esto (pseudocódigo sencilla pero intuitiva):

dll = DllLoad(); 

ptr = dll->alloc(); 

dll->free(ptr); 

DllUnload(dll); 

Esto debe hacerse debido a que el DLL tiene un montón diferente que el proceso original (que carga la DLL).

2

De MSDN Potential Errors Passing CRT Objects Across DLL Boundaries

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

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

Espero que esto ayude.

4

No se puede 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 escapa es, por supuesto, que tiene fugas. 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.

5
  1. La memoria utilizada por un proceso rastreado por el sistema operativo es aplicable al proceso completo y no es específica de una DLL.

  2. memoria se da al programa en trozos por el sistema operativo, llamados montones

  3. Los administradores de pila (malloc/new etc) se dividen más arriba en los trozos y las manos hacia fuera 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á estáticamente vinculada 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 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, un montón privado visible solo para esta copia de malloc, es adquirido del sistema operativo por este malloc y asigna la memoria solicitada por el código dentro de este montón privado.

  8. Cuando el DLL se descarga, descarga su acervo privado, y esta filtración pasa desapercibido ya que todo el montón se devuelve de nuevo 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 a 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ámica 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 vinculación.

2

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 para garantizar que este no sea el caso, el dll perderá la asignación por ciclo de carga, carga, descarga.

Cuestiones relacionadas