2010-11-29 4 views
4

의심스러운 질문 제목에 대해 사과드립니다. 나는 이상한 문제가있어서 왜 그런 일이 일어나는지 전혀 모른다. 다행히도 관련된 코드는 매우 간단합니다. 하지만 우리가 그것에 도착하면 간단히 내 애플 리케이션을 설명하자. 방대한 양의 데이터를 처리하는 다중 스레드 응용 프로그램입니다. in-ram 데이터베이스와 같은 것. 여러 개의 "데이터베이스"가 있고 런타임에로드/언로드 할 수 있습니다. 이제 문제는 메모리 할당 해제입니다. 코드 울부 짖는 소리가 (등 클래스의 이름이 변경되어 있지만,이 문제가되지해야한다) 참조하십시오내 DLL을 사용하는 응용 프로그램에서 새롭거나 삭제되는 이상한 문제

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 

이 작업. nothe 나는 어떤 멋진 것들을 사용하지 않는 사용자 정의 힙 또는 아무것도, 아니 사용자 정의 연산자는 새/삭제 내 DLL이나 내 프로그램에서. 나는 왜 프로그램이 내 dll에 들어가서 거기에 삭제를 호출하는지 전혀 모른다. 그러나 새로운 것으로, 이것은 일어나지 않는다. DeallocTree()을 다음과 같이 변경하면 :

void SS::DeallocTree() 
{ 
    ::operator delete(this->m_tree); 
    this->m_tree = NULL; 
} 

모든 것이 정상적으로 작동합니다. 그러나 이것이 맞는지 확실하지 않습니다. 나는 operator new과 비슷한 것을해야 할까? 그리고이 같은 문제가 다른 곳에서 일어나지 않는다는 것을 어떻게 확신 할 수 있습니까? completness 위해서 나는 또한 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 : * 디버그 \ 이 \ mydll.dll ', 기호가로드.
참고 : 올바르게 내 프로그램의 디버그 버전과 함께 디버그 버전의 DLL을 사용하고 있으며 그 반대의 경우도 마찬가지입니다.
** my_tree는 다음과 같이 선언됩니다.
my_tree * m_tree; // 나무

+0

DLL이 C 런타임에 정적으로 링크되어 있습니까? 아니면 msvcr90d.dll에 동적으로 링크되어 있습니까? – Mud

+0

'm_tree'는 어떻게 선언되어 있습니까? – sharptooth

답변

6

실마리는 콜 스택에있는 것처럼 보입니다. "delete"호출 스택에서는 mydll.dll에서 다양한 삭제 기능 등을 직접 호출한다는 것을 알 수 있습니다. 할당에서 할당은 msvcr90d.dll에 의해 수행됩니다.

당신의 DLL에 설정된 exe와/MTd (또는 릴리스의/MT)에 설정된/MDd (또는/MD 릴리스) 플래그가 있습니다. 그것들을/MDd (또는 릴리스의/MD)로 설정하면 문제가 사라질 것입니다 ... 기본적으로 당신은 exe와 dll을 모두 CRT dll을 호출하는 대신에 2 가지 다른 방법으로 호출하도록 설정할 것입니다 방법 ...

+0

+1, 가능성이 높은 설명으로 들립니다. – sharptooth

+0

고맙습니다. 그게 문제였습니다! – PeterK

관련 문제