Pregunta

Considere este caso:

dll = LoadDLL()
dll->do()

...
void do() {
    char *a = malloc(1024);
}
...

UnloadDLL(dll);

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

¿Fue útil?

Solución

No, no te fugas.

Si combina 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 vinculado no es el mismo montón que el CRT de un dll diferente.

Si se hubiera vinculado con la versión dinámica del CRT, entonces habría una fuga ya que el montón se comparte entre todos los CRT vinculados 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 de dll (es decir, si asigna memoria en un dll, siempre proporcione una rutina para liberarla en el mismo dll)

Otros consejos

  1. La memoria utilizada por un proceso según lo rastreado por el sistema operativo es aplicable a todo el proceso y no es específica de una DLL.

  2. El sistema operativo le da memoria al programa en trozos, llamados montones

  3. Los administradores de almacenamiento dinámico (malloc / new, etc.) dividen aún más los trozos y los entregan al código de solicitud.

  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), se compila una copia privada de CRT con las funciones de CRT que invoca el código de la DLL y se coloca en el binario de la DLL. Malloc también está incluido en esto.

  6. Esta copia privada de malloc se invocará cada vez que el código presente dentro de la DLL estáticamente vinculada 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 la DLL se descarga, descarga su montón privado, y esta fuga pasa desapercibida cuando todo el montón se devuelve al sistema operativo .

  9. Sin embargo, si la DLL está vinculada dinámicamente, la memoria se asigna mediante una única versión compartida de malloc, global a todo el código 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 que se usa para todos los demás códigos que están vinculados en el modo compartido alias dinámico y, por lo tanto, es común. Cualquier fuga de este montón por lo tanto se convierte en una fuga que afecta a todo el proceso.

Editar: se agregaron descripciones del escenario de enlace.

No puedes decirlo. 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 se filtra es que el ejecutable puede esperar razonablemente usar la memoria, ya que la memoria de malloc'ed debe permanecer utilizable hasta que se llame a free.

De MSDN Errores potenciales que pasan objetos CRT a través de límites de DLL

  

Cada copia de la biblioteca CRT tiene un   Estado separado y distinto. Como tal,   Objetos CRT tales como identificadores de archivos,   variables de entorno, y los locales son   Solo valido para la copia del CRT.   donde estos objetos son asignados o   conjunto. Cuando una DLL y sus usuarios usan   diferentes copias de la biblioteca CRT,   no puedes pasar estos objetos CRT   a través del límite DLL y esperar   que sean recogidos correctamente en el   otro lado.

     

También, porque cada copia del CRT   la biblioteca tiene su propio administrador de pilas,   asignación de memoria en una biblioteca CRT   y pasando el puntero a través de una DLL   límite para ser liberado por un diferente   Copia de la biblioteca CRT es un potencial   causa de corrupción del montón.

Espero que esto ayude.

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

A menos que uno haya tenido un cuidado específico para garantizar que este no sea el caso, la dll perderá la asignación por carga, haga, ciclo de descarga.

Uno podría hacer una prueba y ver si hay fugas de memoria. Usted ejecuta una prueba simple 30 veces asignando 1 MB cada vez. Deberías resolverlo bastante rápido.

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

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

dll = DllLoad();

ptr = dll->alloc();

dll->free(ptr);

DllUnload(dll);

Esto se debe hacer porque la DLL tiene un montón diferente al proceso original (que carga la dll).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top