内存越界排查方法



_ASSERTE( _CrtCheckMemory( ) ); ​​​​

 

_DEBUG

The compiler defines _DEBUG when you specify the /MTd or /MDd option. These options specify debug versions of the C run-time library.

 

_CrtCheckMemory

  • Confirms the integrity of the memory blocks allocated in the debug heap (debug version only).
  • Syntax
    • CCopy

      
      int _CrtCheckMemory( void );
      

      Return Value

      If successful, _CrtCheckMemory returns TRUE; otherwise, the function returns FALSE.

      Remarks

      The _CrtCheckMemory function validates memory allocated by the debug heap manager by verifying the underlying base heap and inspecting every memory block. If an error or memory inconsistency is encountered in the underlying base heap, the debug header information, or the overwrite buffers, _CrtCheckMemory generates a debug report with information describing the error condition. When _DEBUG is not defined, calls to _CrtCheckMemory are removed during preprocessing.

      The behavior of _CrtCheckMemory can be controlled by setting the bit fields of the _crtDbgFlag flag using the _CrtSetDbgFlag function. Turning the _CRTDBG_CHECK_ALWAYS_DF bit field ON results in _CrtCheckMemory being called every time a memory allocation operation is requested. Although this method slows down execution, it is useful for catching errors quickly. Turning the _CRTDBG_ALLOC_MEM_DF bit field OFF causes _CrtCheckMemory to not verify the heap and immediately return TRUE.

      Because this function returns TRUE or FALSE, it can be passed to one of the _ASSERT macros to create a simple debugging error handling mechanism. The following example causes an assertion failure if corruption is detected in the heap:

      CCopy

      _ASSERTE( _CrtCheckMemory( ) );
      

      For more information about how _CrtCheckMemory can be used with other debug functions, see Heap State Reporting Functions. For an overview of memory management and the debug heap, see CRT Debug Heap Details.

      Requirements

      RoutineRequired header
      _CrtCheckMemory<crtdbg.h>

 

 

_CrtSetDbgFlag

  • Retrieves or modifies the state of the _crtDbgFlag flag to control the allocation behavior of the debug heap manager (debug version only).
  • Syntax
    • CCopy

      int _CrtSetDbgFlag(
         int newFlag
      );
      

      Parameters

      newFlag
      New state for _crtDbgFlag.

      Return Value

      Returns the previous state of _crtDbgFlag.

      Remarks

      The _CrtSetDbgFlag function allows the application to control how the debug heap manager tracks memory allocations by modifying the bit fields of the _crtDbgFlag flag. By setting the bits (turning on), the application can instruct the debug heap manager to perform special debugging operations, including checking for memory leaks when the application exits and reporting if any are found, simulating low-memory conditions by specifying that freed memory blocks should remain in the heap's linked list, and verifying the integrity of the heap by inspecting each memory block at every allocation request. When _DEBUG is not defined, calls to _CrtSetDbgFlag are removed during preprocessing.

      The following table lists the bit fields for _crtDbgFlag and describes their behavior. Because setting the bits results in increased diagnostic output and reduced program execution speed, these bits are not set (turned off) by default. For more information about these bit fields, see Heap State Reporting Functions.

      Bit fieldDefaultDescription
      _CRTDBG_ALLOC_MEM_DFONON: Enable debug heap allocations and use of memory block type identifiers, such as _CLIENT_BLOCK. OFF: Add new allocations to heap's linked list, but set block type to _IGNORE_BLOCK.

      Can also be combined with any of the heap-frequency check macros.
      _CRTDBG_CHECK_ALWAYS_DFOFFON: Call _CrtCheckMemory at every allocation and deallocation request. OFF: _CrtCheckMemory must be called explicitly.

      Heap-frequency check macros have no effect when this flag is set.
      _CRTDBG_CHECK_CRT_DFOFFON: Include _CRT_BLOCK types in leak detection and memory state difference operations. OFF: Memory used internally by the run-time library is ignored by these operations.

      Can also be combined with any of the heap-frequency check macros.
      _CRTDBG_DELAY_FREE_MEM_DFOFFON: Keep freed memory blocks in the heap's linked list, assign them the _FREE_BLOCK type, and fill them with the byte value 0xDD. OFF: Do not keep freed blocks in the heap's linked list.

      Can also be combined with any of the heap-frequency check macros.
      _CRTDBG_LEAK_CHECK_DFOFFON: Perform automatic leak checking at program exit through a call to _CrtDumpMemoryLeaks and generate an error report if the application failed to free all the memory it allocated. OFF: Do not automatically perform leak checking at program exit.

      Can also be combined with any of the heap-frequency check macros.

      Heap-Check Frequency Macros

      You can specify how often the C run-time library performs validation of the debug heap (_CrtCheckMemory) based on the number of calls to mallocreallocfree, and _msize.

      _CrtSetDbgFlag then inspects the upper 16 bits of the newFlag parameter for a value. The value specified is the number of mallocreallocfree, and _msize calls between _CrtCheckMemory calls. Four predefined macros are provided for this purpose.

      MacroNumber of malloc, realloc, free, and _msize calls between calls to _CrtCheckMemory
      _CRTDBG_CHECK_EVERY_16_DF16
      _CRTDBG_CHECK_EVERY_128_DF128
      _CRTDBG_CHECK_EVERY_1024_DF1024
      _CRTDBG_CHECK_DEFAULT_DF0 (by default, no heap checks)

      By default, _CrtCheckMemory is called once every 1,024 times you call mallocreallocfree, and _msize.

      For example, you could specify a heap check every 16 mallocreallocfree, and _msize operations with the following code:

      CCopy

      #include <crtdbg.h>
      int main( )
      {
          int tmp;
      
          // Get the current bits
          tmp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
      
          // Clear the upper 16 bits and OR in the desired frequency
          tmp = (tmp & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF;
      
          // Set the new bits
          _CrtSetDbgFlag(tmp);
      }
      

      The upper 16 bits of the newFlag parameter are ignored when _CRTDBG_CHECK_ALWAYS_DF is specified. In this case, _CrtCheckMemory is called each time you call mallocreallocfree, and _msize.

      newFlag is the new state to apply to the _crtDbgFlag and is a combination of the values for each of the bit fields.

      To change one or more of these bit fields and create a new state for the flag

      1. Call _CrtSetDbgFlag with newFlag equal to _CRTDBG_REPORT_FLAG to obtain the current _crtDbgFlag state and store the returned value in a temporary variable.

      2. Turn on any bits by a bitwise OR of the temporary variable with the corresponding bitmasks (represented in the application code by manifest constants).

      3. Turn off the other bits by AND-ing the variable with a bitwise NOT of the appropriate bitmasks.

      4. Call _CrtSetDbgFlag with newFlag equal to the value stored in the temporary variable to set the new state for _crtDbgFlag.

      The following code demonstrates how to simulate low-memory conditions by keeping freed memory blocks in the heap's linked list and prevent _CrtCheckMemory from being called at every allocation request:

      CCopy

      // Get the current state of the flag
      // and store it in a temporary variable
      int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
      
      // Turn On (OR) - Keep freed memory blocks in the
      // heap's linked list and mark them as freed
      tmpFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
      
      // Turn Off (AND) - prevent _CrtCheckMemory from
      // being called at every allocation request
      tmpFlag &= ~_CRTDBG_CHECK_ALWAYS_DF;
      
      // Set the new state for the flag
      _CrtSetDbgFlag( tmpFlag );
      

      For an overview of memory management and the debug heap, see CRT Debug Heap Details.

      To disable a flag with the _CrtSetDbgFlag function, you should AND the variable with the bitwise NOT of the bitmask.

      If newFlag is not a valid value, this function invokes the invalid parameter handler, as described in Parameter Validation. If execution is allowed to continue, this function sets errno to EINVAL and returns the previous state of _crtDbgFlag.

      Requirements

      RoutineRequired header
      _CrtSetDbgFlag<crtdbg.h>

      For more compatibility information, see Compatibility.

      Libraries

      Debug versions of C run-time libraries only.

      Example

      CCopy

      // crt_crtsetdflag.c
      // compile with: /c -D_DEBUG /MTd -Od -Zi -W3 /link -verbose:lib /debug
      
      // This program concentrates on allocating and freeing memory
      // blocks to test the functionality of the _crtDbgFlag flag.
      
      #include <string.h>
      #include <malloc.h>
      #include <crtdbg.h>
      
      int main( )
      {
          char *p1, *p2;
          int tmpDbgFlag;
      
          _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
          _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
      
          // Set the debug-heap flag to keep freed blocks in the
          // heap's linked list - This will allow us to catch any
          // inadvertent use of freed memory
          tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
          tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
          tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
          _CrtSetDbgFlag(tmpDbgFlag);
      
          // Allocate 2 memory blocks and store a string in each
          p1 = malloc( 34 );
          p2 = malloc( 38 );
          strcpy_s( p1, 34, "p1 points to a Normal allocation block" );
          strcpy_s( p2, 38, "p2 points to a Client allocation block" );
      
          // Free both memory blocks
          free( p2 );
          free( p1 );
      
          // Set the debug-heap flag to no longer keep freed blocks in the
          // heap's linked list and turn on Debug type allocations (CLIENT)
          tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
          tmpDbgFlag |= _CRTDBG_ALLOC_MEM_DF;
          tmpDbgFlag &= ~_CRTDBG_DELAY_FREE_MEM_DF;
          _CrtSetDbgFlag(tmpDbgFlag);
      
          // Explicitly call _malloc_dbg to obtain the filename and
          // line number of our allocation request and also so we can
          // allocate CLIENT type blocks specifically for tracking
          p1 = _malloc_dbg( 40, _NORMAL_BLOCK, __FILE__, __LINE__ );
          p2 = _malloc_dbg( 40, _CLIENT_BLOCK, __FILE__, __LINE__ );
          strcpy_s( p1, 40, "p1 points to a Normal allocation block" );
          strcpy_s( p2, 40, "p2 points to a Client allocation block" );
      
          // _free_dbg must be called to free the CLIENT block
          _free_dbg( p2, _CLIENT_BLOCK );
          free( p1 );
      
          // Allocate p1 again and then exit - this will leave unfreed
          // memory on the heap
          p1 = malloc( 10 );
      }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值