Detected memory leaks при вызове AfxFreeLibrary
От: Alex_Bukreev  
Дата: 12.05.09 11:39
Оценка:
Есть MFC-приложение и MFC extension DLL. Приложение загружает эту DLL посредством AfxLoadLibrary. При вызове AfxFreeLibrary в окно отладки выдаются сообщения об утечке памяти для всех операций выделения памяти, сделаных между вызовами AfxLoadLibrary и AfxFreeLibrary. Например при выполнении такого куска кода:

    HMODULE hModule = AfxLoadLibrary( _T("MyDLL.dll") );
    int* p1 = new int[ 100 ];
    char* p2 = new char[ 321 ];
    AfxFreeLibrary( hModule );
    delete p1;
    delete p2;


в окно отладки выдаются такие сообщения:

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
От: Pavel Dvorkin Россия  
Дата: 13.05.09 05:14
Оценка:
Здравствуйте, Alex_Bukreev, Вы писали:

A_B>Есть MFC-приложение и MFC extension DLL. Приложение загружает эту DLL посредством AfxLoadLibrary. При вызове AfxFreeLibrary в окно отладки выдаются сообщения об утечке памяти для всех операций выделения памяти, сделаных между вызовами AfxLoadLibrary и AfxFreeLibrary. Например при выполнении такого куска кода:


A_B>
A_B>    HMODULE hModule = AfxLoadLibrary( _T("MyDLL.dll") );
A_B>    int* p1 = new int[ 100 ];
A_B>    char* p2 = new char[ 321 ];
A_B>    AfxFreeLibrary( hModule );
A_B>    delete p1;
A_B>    delete p2;
A_B>


1. А delete все же нормально вызывается или нет ? Имей в виду, что не всем сообщениям об утечке памяти можно верить.
2. Что будет, если этот код выполнить несколько раз ? Сколько будет ликов ?
With best regards
Pavel Dvorkin
Re: Detected memory leaks при вызове AfxFreeLibrary
От: LMars Россия  
Дата: 13.05.09 06:04
Оценка:
Здравствуйте, Alex_Bukreev, Вы писали:

A_B>Есть MFC-приложение и MFC extension DLL. Приложение загружает эту DLL посредством AfxLoadLibrary. При вызове AfxFreeLibrary в окно отладки выдаются сообщения об утечке памяти для всех операций выделения памяти, сделаных между вызовами AfxLoadLibrary и AfxFreeLibrary. Например при выполнении такого куска кода:


A_B>
A_B>    HMODULE hModule = AfxLoadLibrary( _T("MyDLL.dll") );
A_B>    int* p1 = new int[ 100 ];
A_B>    char* p2 = new char[ 321 ];
A_B>    AfxFreeLibrary( hModule );
A_B>    delete p1;
A_B>    delete p2;
A_B>


Случайно это не из-за того, что код с ошибкой? Надо:

    HMODULE hModule = AfxLoadLibrary( _T("MyDLL.dll") );
    int* p1 = new int[ 100 ];
    char* p2 = new char[ 321 ];
    AfxFreeLibrary( hModule );
    delete [] p1;
    delete [] p2;
Re[2]: Detected memory leaks при вызове AfxFreeLibrary
От: Alex_Bukreev  
Дата: 13.05.09 07:08
Оценка:
Здравствуйте, LMars, Вы писали:

LM>Случайно это не из-за того, что код с ошибкой? Надо:


LM>
LM>    HMODULE hModule = AfxLoadLibrary( _T("MyDLL.dll") );
LM>    int* p1 = new int[ 100 ];
LM>    char* p2 = new char[ 321 ];
LM>    AfxFreeLibrary( hModule );
LM>    delete [] p1;
LM>    delete [] p2;
LM>


Да, я потом вспомнил что в таких случаях в delete надо ставить [], но они не помогли
Тем более видите, там утечки памяти показываются не только в тех местах, где я её явно выделяю. Кстати CDynLinkLibrary, это мне ясно, действительно такой объект создаётся в DllMain MFC extension DLL, не понятно только почему он два раза в memory leaks упоминается, ведь адрес один-то.
Re[2]: Detected memory leaks при вызове AfxFreeLibrary
От: Alex_Bukreev  
Дата: 13.05.09 07:36
Оценка:
Здравствуйте, 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
От: Melamed Россия  
Дата: 13.05.09 11:45
Оценка:
Здравствуйте, Alex_Bukreev, Вы писали:

A_B>Здравствуйте, LMars, Вы писали:


LM>>Случайно это не из-за того, что код с ошибкой? Надо:


LM>>
LM>>    HMODULE hModule = AfxLoadLibrary( _T("MyDLL.dll") );
LM>>    int* p1 = new int[ 100 ];
LM>>    char* p2 = new char[ 321 ];
LM>>    AfxFreeLibrary( hModule );
LM>>    delete [] p1;
LM>>    delete [] p2;
LM>>


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
От: Alex_Bukreev  
Дата: 13.05.09 15:21
Оценка:
Здравствуйте, 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 initialization
        if (!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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.