Есть MFC-приложение и MFC extension DLL. Приложение загружает эту DLL посредством AfxLoadLibrary. При вызове AfxFreeLibrary в окно отладки выдаются сообщения об утечке памяти для всех операций выделения памяти, сделаных между вызовами AfxLoadLibrary и AfxFreeLibrary. Например при выполнении такого куска кода:
MyDLL.DLL Initializing!
MyDLL.DLL Terminating!
Detected memory leaks!
Dumping objects ->
...\appdlg.cpp(50) : {108} normal block at 0x0035C8A8, 321 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
...\appdlg.cpp(49) : {107} normal block at 0x0035C6D8, 400 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {82} normal block at 0x00353298, 49 bytes long.
Data: < >x > EC 97 3E 78 0C 00 00 00 20 00 00 00 01 00 00 00
{69} client block at 0x00353218, subtype c0, 64 bytes long.
a CDynLinkLibrary object at $00353218, 64 bytes long
a CDynLinkLibrary object at $00353218, 64 bytes long
Object dump complete.
Кто-нибудь знает, как с этим бороться ? Может тема уже обсуждалась, тогда дайте плиз ссылочку.
Re: Detected memory leaks при вызове AfxFreeLibrary
Здравствуйте, Alex_Bukreev, Вы писали:
A_B>Есть MFC-приложение и MFC extension DLL. Приложение загружает эту DLL посредством AfxLoadLibrary. При вызове AfxFreeLibrary в окно отладки выдаются сообщения об утечке памяти для всех операций выделения памяти, сделаных между вызовами AfxLoadLibrary и AfxFreeLibrary. Например при выполнении такого куска кода:
A_B>
1. А delete все же нормально вызывается или нет ? Имей в виду, что не всем сообщениям об утечке памяти можно верить.
2. Что будет, если этот код выполнить несколько раз ? Сколько будет ликов ?
With best regards
Pavel Dvorkin
Re: Detected memory leaks при вызове AfxFreeLibrary
Здравствуйте, Alex_Bukreev, Вы писали:
A_B>Есть MFC-приложение и MFC extension DLL. Приложение загружает эту DLL посредством AfxLoadLibrary. При вызове AfxFreeLibrary в окно отладки выдаются сообщения об утечке памяти для всех операций выделения памяти, сделаных между вызовами AfxLoadLibrary и AfxFreeLibrary. Например при выполнении такого куска кода:
A_B>
Да, я потом вспомнил что в таких случаях в delete надо ставить [], но они не помогли
Тем более видите, там утечки памяти показываются не только в тех местах, где я её явно выделяю. Кстати CDynLinkLibrary, это мне ясно, действительно такой объект создаётся в DllMain MFC extension DLL, не понятно только почему он два раза в memory leaks упоминается, ведь адрес один-то.
Re[2]: Detected memory leaks при вызове AfxFreeLibrary
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>1. А delete все же нормально вызывается или нет ? Имей в виду, что не всем сообщениям об утечке памяти можно верить.
1. delete вызывается нормально. Если убрать вызов AfxFreeLibrary то при завершении программы выдаются только такие memory leaks:
Detected memory leaks!
Dumping objects ->
{69} client block at 0x00353218, subtype c0, 64 bytes long.
a CDynLinkLibrary object at $00353218, 64 bytes long
a CDynLinkLibrary object at $00353218, 64 bytes long
Object dump complete.
PD>2. Что будет, если этот код выполнить несколько раз ? Сколько будет ликов ?
Столько, сколько этот код будет выполняться. Лики появляются именно при вызове AfxFreeLibrary. Я понимаю, что скорее всего это так называемые false memory leaks. Это видимо какой-то глюк в MFC, из-за которого при вызове AfxFreeLibrary для MFC extension DLL выдаются лики на всю выделенную к данному моменту память.
Re[3]: Detected memory leaks при вызове AfxFreeLibrary
A_B>Да, я потом вспомнил что в таких случаях в delete надо ставить [], но они не помогли A_B>Тем более видите, там утечки памяти показываются не только в тех местах, где я её явно выделяю. Кстати CDynLinkLibrary, это мне ясно, действительно такой объект создаётся в DllMain MFC extension DLL, не понятно только почему он два раза в memory leaks упоминается, ведь адрес один-то.
Глюк явно в DLL, которую вы загружаете, а точнее в функции DllMain, которая вызывается при загрузки и выгрузке динамической библиотеки. Наверняка при загрузки библиотеки создается элемент класса, а при выгрузке он не уничтожается, что ведет к утечки памяти в программе
Вот пример, как должна быть написана DllMain функция в библиотеки
Array2D *Temp;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
// Выполняется при загрузки библиотеки
Temp = new Array2D;
break;
}
case DLL_PROCESS_DETACH:
{
// Выпольняется при выгрузке библиотекиdelete Temp;
break;
}
}
return TRUE;
}
Re[4]: Detected memory leaks при вызове AfxFreeLibrary
Здравствуйте, Melamed, Вы писали:
M>Глюк явно в DLL, которую вы загружаете, а точнее в функции DllMain, которая вызывается при загрузки и выгрузке динамической библиотеки. Наверняка при загрузки библиотеки создается элемент класса, а при выгрузке он не уничтожается, что ведет к утечки памяти в программе
M>Вот пример, как должна быть написана DllMain функция в библиотеки
M>
M>Array2D *Temp;
M>BOOL APIENTRY DllMain( HANDLE hModule,
M> DWORD ul_reason_for_call,
M> LPVOID lpReserved
M> )
M>{
M> switch(ul_reason_for_call)
M> {
M> case DLL_PROCESS_ATTACH:
M> {
M>// Выполняется при загрузки библиотеки
M> Temp = new Array2D;
M> break;
M> }
M> case DLL_PROCESS_DETACH:
M> {
M>// Выпольняется при выгрузке библиотеки
M> delete Temp;
M> break;
M> }
M> }
M> return TRUE;
M>}
M>
Я не изменял функцию DllMain, созданую студией, вот её код:
static AFX_EXTENSION_MODULE MyDLLDLL = { NULL, NULL };
#ifdef _MANAGED
#pragma managed(push, off)
#endif
extern"C"int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("MyDLL.DLL Initializing!\n");
// Extension DLL one-time initializationif (!AfxInitExtensionModule(MyDLLDLL, hInstance))
return 0;
// Insert this DLL into the resource chain
// NOTE: If this Extension DLL is being implicitly linked to by
// an MFC Regular DLL (such as an ActiveX Control)
// instead of an MFC application, then you will want to
// remove this line from DllMain and put it in a separate
// function exported from this Extension DLL. The Regular DLL
// that uses this Extension DLL should then explicitly call that
// function to initialize this Extension DLL. Otherwise,
// the CDynLinkLibrary object will not be attached to the
// Regular DLL's resource chain, and serious problems will
// result.new CDynLinkLibrary(MyDLLDLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("MyDLL.DLL Terminating!\n");
// Terminate the library before destructors are called
AfxTermExtensionModule(MyDLLDLL);
}
return 1; // ok
}
#ifdef _MANAGED
#pragma managed(pop)
#endif