извините за загадочный заголовок вопроса. У меня странная проблема, и я понятия не имею, почему это происходит. К счастью, код довольно прост. Но прежде чем мы доберемся до этого, позвольте мне кратко описать мое приложение. Это многопоточное приложение, которое обслуживает большой объем данных. Что-то вроде оперативной базы данных. Можно иметь несколько «баз данных» и загружать / выгружать их во время выполнения. Теперь проблема с освобождением памяти. Пожалуйста, смотрите код ниже (названия классов и т. Д. Изменены, но это не должно иметь значения):
void SS::AllocTree( double*** pba, int i, int d, int b, int split )
{
this->m_tree = new my_tree( pba, i, d, b, split );
}
void SS::DeallocTree()
{
delete this->m_tree;
this->m_tree = NULL;
}
Каждый раз, когда вызывается delete this->m_tree
, происходит сбой программы. Трассировка стека выглядит следующим образом:
mydll.dll!_free_base(void * pBlock=0x0000000008496f70) Line 109 + 0x14 bytes C
mydll.dll!_free_dbg_nolock(void * pUserData=0x0000000008496fa0, int nBlockUse=0x00000001) Line 1428 C++
mydll.dll!_free_dbg(void * pUserData=0x0000000008496fa0, int nBlockUse=0x00000001) Line 1258 + 0xe bytes C++
mydll.dll!operator delete(void * pUserData=0x0000000008496fa0) Line 54 + 0x12 bytes C++
mydll.dll!my_tree::`vector deleting destructor'() + 0x94 bytes C++
myprog.exe!SS::DeallocTree() Line 57 + 0x34 bytes C++
myprog.exe!SSUnloader(void * arg=0x00000000084d6f80) Line 1038 C++
msvcr90d.dll!_callthreadstart() Line 295 C
msvcr90d.dll!_threadstart(void * ptd=0x00000000084dad30) Line 277 C
Вот трассировка стека для выделения дерева:
msvcr90d.dll!malloc(unsigned __int64 nSize=0x0000000000000058) Line 56 + 0x21 bytes C++
msvcr90d.dll!operator new(unsigned __int64 size=0x0000000000000058) Line 59 + 0xa bytes C++
myprog.exe!SS::AllocTree(double * * * pba=0x0000000008458ff0, int i=0x00000bde, int d=0x00000010, int b=0x00000008, int split=0x00000001) Line 52 + 0xa bytes C++
myprog.exe!SSLoader(void * arg=0x000000000843cf80) Line 932 C++
msvcr90d.dll!_callthreadstart() Line 295 C
msvcr90d.dll!_threadstart(void * ptd=0x0000000008440d30) Line 277 C
Как видите, загрузка / выгрузка выполняется отдельным потоком, специально созданным для этой задачи. Не то, что я не использую какие-либо причудливые вещи, никакие пользовательские кучи или что-либо, никакой пользовательский оператор new / delete в моей dll или моей программе. Я понятия не имею, почему программа заходит в мою DLL и вызывает там удаление, но с новым этого не происходит. Если я изменю DeallocTree()
, чтобы он выглядел так:
void SS::DeallocTree()
{
::operator delete( this->m_tree );
this->m_tree = NULL;
}
Тогда все работает нормально. Однако я не уверен, правильно ли это. Должен ли я сделать что-то подобное для оператора нового? И как я могу быть уверен, что эта проблема не встречается больше нигде? Для полноты картины я также прилагаю трассировку стека для этой версии DeallocTree ():
msvcr90d.dll!operator delete(void * pUserData=0x00000000086f5fa0) Line 45 + 0xa bytes C++
myprog.exe!SS::DeallocTree() Line 58 C++
myprog.exe!SSUnloader(void * arg=0x0000000008735f80) Line 1038 C++
msvcr90d.dll!_callthreadstart() Line 295 C
msvcr90d.dll!_threadstart(void * ptd=0x0000000008739d30) Line 277 C
Может кто-нибудь объяснить мне, что здесь происходит?
РЕДАКТИРОВАТЬ:
Чтобы уточнить:
my.dll загружается динамически - вывод VS 2008:
myprog.exe ': загружен' C: * \ Debug \ mydll.dll ', символы загружены.
Примечание: я правильно использую отладочную версию DLL с отладочной версией моей программы и наоборот с выпуском.
** my_tree объявлено как: my_tree * m_tree; // дерево