Se informan de pérdidas de memoria cuando utiliza varios archivos DLL de MFC

Síntomas

Cuando se depura un proyecto que contenga los archivos de DLL MFC estándar (USRDLL) o controles ActiveX (OCX), puede ver pérdidas de memoria similar al siguiente en el depurador:

   a CDynLinkLibrary object at $00410F70, 64 bytes long
a CDynLinkLibrary object at $00410F70, 64 bytes long
{38} client block at 0x00410D80, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $00410D80, 64 bytes long
a CDynLinkLibrary object at $00410D80, 64 bytes long
{36} client block at 0x00410C60, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $00410C60, 64 bytes long
a CDynLinkLibrary object at $00410C60, 64 bytes long

Causa

Se informa de estas pérdidas de memoria cuando se cargan varias versiones de las DLL de MFC en el mismo proceso. Dado que MFC DLL de extensión (AFXDLL) requieren la misma DLL de MFC exacta como la aplicación de llamada, este problema puede producirse sólo cuando se utilizan archivos de DLL MFC estándar (USRDLL) o controles de ActiveX (OCX) que utilizan la versión compartida de MFC.


El caso más común es una combinación de ANSI (MFC4xd.DLL) y las versiones de MFC UNICODE (MFC4xxUd.DLL) en el mismo proceso. Esto también puede ocurrir cuando se mezclan MFC42d.DLL y MFC40d.DLL.

Solución

Estas notificaciones de pérdida de memoria son falsas y pueden omitirse. Puesto que ninguna copia de MFC sabe acerca de los demás, no es fácil detener estas pérdidas false desde el que se informa. Sin embargo, es posible separar las pérdidas false de las posibles pérdidas reales. Esto puede hacerse reemplazando CWinApp::ExitInstance() en el EXE y DLL y colocar la sentencia TRACE() en ellas:

   int CTestDllApp::ExitInstance()   {
TRACE(_T("ExitInstance() for regular DLL: TESTDLL\n"));

return CWinApp::ExitInstance();
}

Sólo las pérdidas de memoria que se detectan después de la última CWinApp::ExitInstance() son pérdidas de memoria es true.

Estado

Este comportamiento es por diseño.

Más información

Tenga en cuenta la aplicación o DLL siguientes:

     -------------               --------------
= = = =
= MFC = Calls = MFC =
= APP = ------------> = USRDLL =
= = = =
= = = =
------------- --------------
| |
| |
| Calls | Calls
| |
\/ \/
------------- --------------
= = = =
= = = =
= MFC40d = = MFC40Ud =
= DLL = = DLL =
= = = =
------------- --------------
\ /
\ /
\ Calls / Calls
\ /
\/ \/
-------------
= =
= =
= MSVCR40d =
= (CRT) =
= =
-------------

La aplicación MFC creada con la versión ANSI (MFC40d.DLL) de MFC llama a la USRDLL MFC, que se incluye con la versión UNICODE (MFC40Ud.DLL) de MFC. Ambas versiones MFC utilizan la misma DLL C run-time (CRT), MSVCR40d.DLL. Dado que MFC USRDLL "cajas negras", no debería haber ningún problema con una llamada a un archivo USRDLL MFC de UNICODE desde una aplicación de MFC ANSI.


Sin embargo, puesto que el UNICODE (MFC40ud.DLL) y los archivos DLL de MFC ANSI (MFC40d.DLL) utilizan la misma DLL de CRT, pérdidas de memoria falsas se notifican en todos los objetos asignados en el USRDLL MFC. Esto se produce porque MFC se basa en el archivo DLL de CRT para asignar y realizar el seguimiento de toda la memoria. No separa las asignaciones de memoria desde las distintas versiones de MFC. Cuando se descarga una de las DLL de MFC, llama el CRT para realizar un volcado de memoria, suponiendo que todo lo deja en el montón es una pérdida de memoria. Sin embargo, esta suposición es incorrecta ya que hay dos copias múltiples de MFC en la memoria.


(c) 1997 Microsoft Corporation, Reservados todos los derechos. Contribuciones por Kelly Marie Ward, Microsoft Corporation.


Propiedades

Id. de artículo: 167929 - Última revisión: 01/08/2017 - Revisión: 1

Comentarios