Debugging 使用Visual C+可以做哪些有用的事情+;调试CRT分配挂钩,除了查找可复制内存泄漏? VisualC++调试运行库的特点是所谓的。工作方式如下:定义回调并调用\u CrtSetAllocHook()来设置回调。现在,每当内存分配/解除分配/重新分配完成时,CRT调用该回调并传递少量参数

Debugging 使用Visual C+可以做哪些有用的事情+;调试CRT分配挂钩,除了查找可复制内存泄漏? VisualC++调试运行库的特点是所谓的。工作方式如下:定义回调并调用\u CrtSetAllocHook()来设置回调。现在,每当内存分配/解除分配/重新分配完成时,CRT调用该回调并传递少量参数,debugging,visual-c++,memory,memory-management,Debugging,Visual C++,Memory,Memory Management,我成功地使用了一个分配钩子来找到一个-基本上CRT报告在程序终止时有一个分配号为N(每个程序运行时N都是相同的)的未混合块,因此我在钩子中写了以下内容: int MyAllocHook( int allocType, void* userData, size_t size, int blockType, long requestNumber, const unsigned char* filename, int lineNumber) { if( requestNumber

我成功地使用了一个分配钩子来找到一个-基本上CRT报告在程序终止时有一个分配号为N(每个程序运行时N都是相同的)的未混合块,因此我在钩子中写了以下内容:

int MyAllocHook( int allocType, void* userData, size_t size, int blockType, 
    long requestNumber, const unsigned char* filename, int lineNumber)
{
     if( requestNumber == TheNumberReported ) {
         Sleep( 0 );// a line to put breakpoint on
     }
     return TRUE;
}
由于每次报告泄漏时都使用相同的分配号,所以我可以在if语句中放置一个断点,等待它被命中,然后检查调用堆栈


使用分配挂钩还可以做哪些有用的事情?

您可以保留每个分配请求的记录,然后在调用解除分配后将其删除,例如:这可以帮助您跟踪比这更糟糕的内存泄漏问题


只是我脑海中的第一个想法

您还可以使用它查找不可恢复的内存泄漏:

  • 创建一个数据结构,将分配的指针映射到其他信息
  • 在分配挂钩中,您可以查询当前调用堆栈(StackWalk函数),并将调用堆栈存储在数据结构中
  • 在反分配挂钩中,删除该分配的调用堆栈信息
  • 在应用程序结束时,循环数据结构并报告所有调用堆栈。这些地方分配了内存,但没有释放内存
解除分配时,“requestNumber”值不会传递给函数(MS VS 2008)。如果没有此号码,您将无法跟踪您的分配情况。但是,您可以查看堆头并从中提取该值:

注意:这取决于编译器,编译器可能会在不发出通知/警告的情况下更改。

//此结构是MS VS 2008使用的堆头的副本。
//此信息是在调试模式下为每个分配的内存对象添加前缀。
结构MsVS\U CrtMemBlockHeader{
MsVS\U CrtMemBlockHeader*\U next;
MSV\u CrtMemBlockHeader*\u prev;
char*_;
国际在线;
国际泛化;
国际洛克使用;
长期需求;
char_gap[4];
};

int myallook(..){//与所讨论的相同 如果(nAllocType==\u钩子\u自由){ //requestNumber不会免费传递给钩子。 //但是,该值存储在堆头中。 size\u t headerSize=sizeof(MsVS\u CrtMemBlockHeader); MsVS_CrtMemBlockHeader*pHead; 尺寸ptr=(尺寸)pvData-头部尺寸; pHead=(MsVS_CrtMemBlockHeader*)(ptr); long requestNumber=pHead->\u lRequest; //做你想做的事来跟踪这一分配。 } }


// This struct is a copy of the heap header used by MS VS 2008.
// This information is prepending each allocated memory object in debug mode.
struct MsVS_CrtMemBlockHeader {
    MsVS_CrtMemBlockHeader * _next;
    MsVS_CrtMemBlockHeader * _prev;
    char * _szFilename;
    int _nLine;
    int _nDataSize;
    int _nBlockUse;
    long _lRequest;
    char _gap[4];
};

int MyAllocHook(..) { // same as in question if(nAllocType == _HOOK_FREE) { // requestNumber isn't passed on to the Hook on free. // However in the heap header this value is stored. size_t headerSize = sizeof(MsVS_CrtMemBlockHeader); MsVS_CrtMemBlockHeader* pHead; size_t ptr = (size_t) pvData - headerSize; pHead = (MsVS_CrtMemBlockHeader*) (ptr); long requestNumber = pHead->_lRequest; // Do what you like to keep track of this allocation. } }