user-0 提问: 如何捕捉free异常

回复:
user: user-1
content: Debug Routines With this version, Visual C++ introduces debug support for the C run-time library. The new debug version of the library supplies many diagnostic services that make debugging programs easier and allow developers to:   Step directly into run-time functions during debugging   Resolve assertions, errors, and exceptions   Trace heap allocations and prevent memory leaks   Report debug messages to the user  To use these routines, the _DEBUG flag must be defined. All of these routines do nothing in a retail build of an application. For more information on how to use the new debug routines, see Using C Run-Time Library Debugging Support.  Debug Versions of the C Run-time Library Routines  Routine Use  _ASSERT Evaluate an expression and generates a debug report when the result is FALSE  _ASSERTE Similar to _ASSERT, but includes the failed expression in the generated report  _CrtCheckMemory Confirm the integrity of the memory blocks allocated on the debug heap  _CrtDbgReport Generate a debug report with a user message and send the report to three possible destinations  _CrtDoForAllClientObjects Call an application-supplied function for all _CLIENT_BLOCK types on the heap  _CrtDumpMemoryLeaks Dump all of the memory blocks on the debug heap when a significant memory leak has occurred  _CrtIsValidHeapPointer Verify that a specified pointer is in the local heap  _CrtIsMemoryBlock Verify that a specified memory block is located within the local heap and that it has a valid debug heap block type identifier  _CrtIsValidPointer Verify that a specified memory range is valid for reading and writing  _CrtMemCheckpoint Obtain the current state of the debug heap and store it in an application-supplied _CrtMemState structure  _CrtMemDifference Compare two memory states for significant differences and return the results  _CrtMemDumpAllObjectsSince Dump information about objects on the heap since a specified checkpoint was taken or from the start of program execution  _CrtMemDumpStatistics Dump the debug header information for a specified memory state in a user-readable form  _CrtSetAllocHook Install a client-defined allocation function by hooking it into the C run-time debug memory allocation process  _CrtSetBreakAlloc Set a breakpoint on a specified object allocation order number  _CrtSetDbgFlag Retrieve or modify the state of the _crtDbgFlag flag to control the allocation behavior of the debug heap manager  _CrtSetDumpClient Install an application-defined function that is called every time a debug dump function is called to dump _CLIENT_BLOCK type memory blocks  _CrtSetReportFile Identify the file or stream to be used as a destination for a specific report type by _CrtDbgReport  _CrtSetReportHook Install a client-defined reporting function by hooking it into the C run-time debug reporting process  _CrtSetReportMode Specify the general destination(s) for a specific report type generated by _CrtDbgReport  _RPT[0,1,2,3,4] Track the application’s progress by generating a debug report by calling _CrtDbgReport with a format string and a variable number of arguments. Provides no source file and line number information.  _RPTF[0,1,2,3,4] Similar to the _RPTn macros, but provides the source file name and line number where the report request originated  _calloc_dbg Allocate a specified number of memory blocks on the heap with additional space for a debugging header and overwrite buffers  _expand_dbg Resize a specified block of memory on the heap by expanding or contracting the block  _free_dbg Free a block of memory on the heap  _malloc_dbg Allocate a block of memory on the heap with additional space for a debugging header and overwrite buffers  _msize_dbg Calculate the size of a block of memory on the heap  _realloc_dbg Reallocate a specified block of memory on the heap by moving and/or resizing the block    The debug routines can be used to step through the source code for most of the other C run-time routines during the debugging process. However, Microsoft considers some technology to be proprietary and, therefore, does not provide the source code for these routines. Most of these routines belong to either the exception handling or floating-point processing groups, but a few others are included as well. The following table lists these routines.  C Run-time Routines that are Not Available in Source Code Form  acos _fpclass _nextafter  asin _fpieee_flt pow  atan, atan2 _fpreset printf, wprintf1  _cabs frexp _scalb  ceil _hypot scanf, wscanf1  _chgsign _isnan setjmp  _clear87, _clearfp _j0 sin  _control87, _controlfp _j1 sinh  _copysign _jn sqrt  cos ldexp _status87, _statusfp  cosh log tan  exp log10 tanh  fabs _logb _y0  _finite longjmp _y1  floor _matherr _yn  fmod modf      1   Although source code is available for most of this routine, it makes an internal call to another routine for which source code is not provided.  Some C run-time functions and C++ operators behave differently when called from a debug build of an application. (Note that a debug build of an application can be done by either defining the _DEBUG flag or by linking with a debug version of the C run-time library.) The behavioral differences usually consist of extra features or information provided by the routine to support the debugging process. The following table lists these routines.  Routines that Behave Differently in a Debug Build of an Application  C abort routine C++ delete operator  C assert routine C++ new operator    For more information about using the debug versions of the C++ operators in the preceding table, see Using the Debug Heap from C++.

user: user-1
content: _CrtDumpMemoryLeaks Dumps all of the memory blocks in the debug heap when a memory leak has occurred (debug version only).  int _CrtDumpMemoryLeaks( void );  Routine Required Header Compatibility  _CrtDumpMemoryLeaks <crtdbg.h> Win NT, Win 95    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBCD.LIB Single thread static library, debug version  LIBCMTD.LIB Multithread static library, debug version  MSVCRTD.LIB Import library for MSVCRTD.DLL, debug version    Return Value  _CrtDumpMemoryLeaks returns TRUE if a memory leak is found; otherwise, the function returns FALSE.  Remarks  The _CrtDumpMemoryLeaks function determines whether a memory leak has occurred since the start of program execution. When a leak is found, the debug header information for all of the objects in the heap is dumped in a user-readable form. When _DEBUG is not defined, calls to _CrtDumpMemoryLeaks are removed during preprocessing.  _CrtDumpMemoryLeaks is frequently called at the end of program execution to verify that all memory allocated by the application has been freed. The function can be called automatically at program termination by turning on the _CRTDBG_LEAK_CHECK_DF bit field of the _crtDbgFlag flag using the _CrtSetDbgFlag function.  _CrtDumpMemoryLeaks calls _CrtMemCheckpoint to obtain the current state of the heap and then scans the state for blocks that have not been freed. When an unfreed block is encountered, _CrtDumpMemoryLeaks calls _CrtMemDumpAllObjectsSince to dump information for all of the objects allocated in the heap from the start of program execution.   By default, internal C run-time blocks (_CRT_BLOCK) are not included in memory dump operations. The _CrtSetDbgFlag function can be used to turn on the _CRTDBG_CHECK_CRT_DF bit of _crtDbgFlag to include these blocks in the leak detection process.  For more information about heap state functions and the _CrtMemState structure, see the Heap State Reporting Functions. For information about how memory blocks are allocated, initialized, and managed in the debug version of the base heap, see Memory Management and the Debug Heap.  Example  /*****************************************************************  *  EXAMPLE  1                                                   *  *  This simple program illustrates the basic debugging features *  *  of the C runtime libraries, and the kind of debug output     *  *  that these features generate.                                *  *****************************************************************/  #include <stdio.h> #include <string.h> #include <malloc.h> #include <crtdbg.h>  // This routine place comments at the head of a section of debug output void OutputHeading( const char * explanation ) {    _RPT1( _CRT_WARN, "\n\n%s:\n**************************************\ ************************************\n", explanation ); }  // The following macros set and clear, respectively, given bits // of the C runtime library debug flag, as specified by a bitmask. #ifdef   _DEBUG #define  SET_CRT_DEBUG_FIELD(a) \             _CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)) #define  CLEAR_CRT_DEBUG_FIELD(a) \             _CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)) #else #define  SET_CRT_DEBUG_FIELD(a)   ((void) 0) #define  CLEAR_CRT_DEBUG_FIELD(a) ((void) 0) #endif   void main( ) {    char *p1, *p2;    _CrtMemState s1, s2, s3;     // Send all reports to STDOUT    _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );    _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );    _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );    _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );    _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );     // Allocate 2 memory blocks and store a string in each    p1 = malloc( 34 );    strcpy( p1, "This is the p1 string (34 bytes)." );     p2 = malloc( 34 );    strcpy( p2, "This is the p2 string (34 bytes)." );      OutputHeading(        "Use _ASSERTE to check that the two strings are identical" );    _ASSERTE( strcmp( p1, p2 ) == 0 );     OutputHeading(        "Use a _RPT macro to report the string contents as a warning" );    _RPT2( _CRT_WARN, "p1 points to '%s' and \np2 points to '%s'\n", p1, p2 );     OutputHeading(        "Use _CRTMemDumpAllObjectsSince to check the p1 and p2 allocations" );    _CrtMemDumpAllObjectsSince( NULL );     free( p2 );     OutputHeading(        "Having freed p2, dump allocation information about p1 only" );    _CrtMemDumpAllObjectsSince( NULL );     // Store a memory checkpoint in the s1 memory-state structure    _CrtMemCheckpoint( &s1 );     // Allocate another block, pointed to by p2    p2 = malloc( 38 );    strcpy( p2, "This new p2 string occupies 38 bytes.");     // Store a 2nd memory checkpoint in s2    _CrtMemCheckpoint( &s2 );     OutputHeading(        "Dump the changes that occurred between two memory checkpoints" );    if ( _CrtMemDifference( &s3, &s1, &s2 ) )       _CrtMemDumpStatistics( &s3 );     // Free p2 again and store a new memory checkpoint in s2    free( p2 );    _CrtMemCheckpoint( &s2 );     OutputHeading(        "Now the memory state at the two checkpoints is the same" );    if ( _CrtMemDifference( &s3, &s1, &s2 ) )       _CrtMemDumpStatistics( &s3 );     strcpy( p1, "This new p1 string is over 34 bytes" );    OutputHeading( "Free p1 after overwriting the end of the allocation" );    free( p1 );     // Set the debug-heap flag so that freed blocks are kept on the    // linked list, to catch any inadvertent use of freed memory    SET_CRT_DEBUG_FIELD( _CRTDBG_DELAY_FREE_MEM_DF );     p1 = malloc( 10 );    free( p1 );    strcpy( p1, "Oops" );     OutputHeading( "Perform a memory check after corrupting freed memory" );    _CrtCheckMemory( );     // Use explicit calls to _malloc_dbg to save file name and line number    // information, and also to allocate Client type blocks for tracking    p1 = _malloc_dbg( 40, _NORMAL_BLOCK, __FILE__, __LINE__ );    p2 = _malloc_dbg( 40, _CLIENT_BLOCK, __FILE__, __LINE__ );    strcpy( p1, "p1 points to a Normal allocation block" );    strcpy( p2, "p2 points to a Client allocation block" );     // You must use _free_dbg to free a Client block    OutputHeading(        "Using free( ) to free a Client block causes an assertion failure" );    free( p1 );    free( p2 );     p1 = malloc( 10 );    OutputHeading( "Examine outstanding allocations (dump memory leaks)" );    _CrtDumpMemoryLeaks( );     // Set the debug-heap flag so that memory leaks are reported when    // the process terminates. Then, exit.    OutputHeading( "Program exits without freeing a memory block" );    SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF ); }  Output  Use _ASSERTE to check that the two strings are identical: ************************************************************************** C:\DEV\EXAMPLE1.C(56) : Assertion failed: strcmp( p1, p2 ) == 0   Use a _RPT macro to report the string contents as a warning: ************************************************************************** p1 points to 'This is the p1 string (34 bytes).' and  p2 points to 'This is the p2 string (34 bytes).'   Use _CRTMemDumpAllObjectsSince to check the p1 and p2 allocations: ************************************************************************** Dumping objects -> {13} normal block at 0x00660B5C, 34 bytes long  Data: <This is the p2 s> 54 68 69 73 20 69 73 20 74 68 65 20 70 32 20 73  {12} normal block at 0x00660B10, 34 bytes long  Data: <This is the p1 s> 54 68 69 73 20 69 73 20 74 68 65 20 70 31 20 73  Object dump complete.   Having freed p2, dump allocation information about p1 only: ************************************************************************** Dumping objects -> {12} normal block at 0x00660B10, 34 bytes long  Data: <This is the p1 s> 54 68 69 73 20 69 73 20 74 68 65 20 70 31 20 73  Object dump complete.   Dump the changes that occurred between two memory checkpoints: ************************************************************************** 0 bytes in 0 Free Blocks. 38 bytes in 1 Normal Blocks. 0 bytes in 0 CRT Blocks. 0 bytes in 0 IgnoreClient Blocks. 0 bytes in 0 (null) Blocks. Largest number used: 4 bytes. Total allocations: 38 bytes.   Now the memory state at the two checkpoints is the same: **************************************************************************   Free p1 after overwriting the end of the allocation: ************************************************************************** memory check error at 0x00660B32 = 0x73, should be 0xFD. memory check error at 0x00660B33 = 0x00, should be 0xFD. DAMAGE: after Normal block (#12) at 0x00660B10.   Perform a memory check after corrupting freed memory: ************************************************************************** memory check error at 0x00660B10 = 0x4F, should be 0xDD. memory check error at 0x00660B11 = 0x6F, should be 0xDD. memory check error at 0x00660B12 = 0x70, should be 0xDD. memory check error at 0x00660B13 = 0x73, should be 0xDD. memory check error at 0x00660B14 = 0x00, should be 0xDD. DAMAGE: on top of Free block at 0x00660B10. DAMAGED located at 0x00660B10 is 10 bytes long.   Using free( ) to free a Client block causes an assertion failure: ************************************************************************** dbgheap.c(1039) : Assertion failed: pHead->nBlockUse == nBlockUse   Examine outstanding allocations (dump memory leaks): ************************************************************************** Detected memory leaks! Dumping objects -> {18} normal block at 0x00660BE4, 10 bytes long  Data: <          > CD CD CD CD CD CD CD CD CD CD  Object dump complete.   Program exits without freeing a memory block: ************************************************************************** Detected memory leaks! Dumping objects -> {18} normal block at 0x00660BE4, 10 bytes long  Data: <          > CD CD CD CD CD CD CD CD CD CD  Object dump complete.

user: user-1
content: free Deallocates or frees a memory block.  void free( void *memblock );  Function Required Header Compatibility  free <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  None  Parameter  memblock  Previously allocated memory block to be freed  Remarks  The free function deallocates a memory block (memblock) that was previously allocated by a call to calloc, malloc, or realloc. The number of freed bytes is equivalent to the number of bytes requested when the block was allocated (or reallocated, in the case of realloc). If memblock is NULL, the pointer is ignored and free immediately returns. Attempting to free an invalid pointer (a pointer to a memory block that was not allocated by calloc, malloc, or realloc) may affect subsequent allocation requests and cause errors.  After a memory block has been freed, _heapmin minimizes the amount of free memory on the heap by coalescing the unused regions and releasing them back to the operating system. Freed memory that is not released to the operating system is restored to the free pool and is available for allocation again.  When the application is linked with a debug version of the C run-time libraries, free resolves to _free_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.  Example  /* MALLOC.C: This program allocates memory with  * malloc, then frees the memory with free.  */  #include <stdlib.h>         /* For _MAX_PATH definition */ #include <stdio.h> #include <malloc.h>  void main( void ) {    char *string;     /* Allocate space for a path name */    string = malloc( _MAX_PATH );    if( string == NULL )       printf( "Insufficient memory available\n" );    else    {       printf( "Memory space allocated for path name\n" );       free( string );       printf( "Memory freed\n" );    } }   Output  Memory space allocated for path name Memory freed   Memory Allocation Routines  See Also   _alloca, calloc, malloc, realloc, _free_dbg, _heapmin

user: user-0
content: 引用 1 楼 zhao4zhong1 的回复:Windows：崩溃的时候在弹出的对话框按相应按钮进入调试，按A+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。  Linux：进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令 我的意思是程序中如何去判断free异常了，例如fclose可以查看他的返回值，free怎么处理呢？

user: user-1
content: Windows：崩溃的时候在弹出的对话框按相应按钮进入调试，按A+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。  Linux：进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令