⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfc10.php

📁 php网页版的mfc教程 不是十分详细 但是很精练 我是新手不是十分会欣赏
💻 PHP
📖 第 1 页 / 共 2 页
字号:
<HTML><HEAD><TITLE>MFC教程_ 内存分配方式和调试机制</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2800.1458" name=GENERATOR></HEAD>
<BODY bgColor=#ffffff>
<OL start=10>
  <P align=justify>
  <LI><A name=_Toc445889121></A><A name=_Toc445782524></A><A 
  name=_Toc452640983></A><A name=_Toc457299092></A><B>内存分配方式和调试机制</B> 
  <P></P>
  <OL>
    <P align=justify>
    <LI><B><A name=_Toc445889122></A><A name=_Toc445782525></A><A 
    name=_Toc452640984></A><A name=_Toc457299093></A>M内存分配</B> 
    <P></P>
    <OL>
      <P align=justify>
      <LI><B><A name=_Toc445889123></A><A name=_Toc445782526></A><A 
      name=_Toc452640985></A><A name=_Toc457299094></A>内存分配函数</B> 
      <P></P></LI></OL></LI></OL></LI></OL>
<P align=justify>MFCWin32或者C语言的内存分配API,有四种内存分配API可供使用。</P>
<OL>
  <P align=justify>
  <LI>Win32的堆分配函数 
  <P></P>
  <P 
  align=justify>每一个进程都可以使用堆分配函数创建一个私有的堆──调用进程地址空间的一个或者多个页面。DLL创建的私有堆必定在调用DLL的进程的地址空间内,只能被调用进程访问。</P>
  <P 
  align=justify>HeapCreate用来创建堆;HeapAlloc用来从堆中分配一定数量的空间,HeapAlloc分配的内存是不能移动的;HeapSize可以确定从堆中分配的空间的大小;HeapFree用来释放从堆中分配的空间;HeapDestroy销毁创建的堆。</P>
  <P align=justify></P>
  <LI>Windows传统的全局或者局部内存分配函数 
  <P></P>
  <P 
  align=justify>由于Win32采用平面内存结构模式,Win32下的全局和局部内存函数除了名字不同外,其他完全相同。任一函数都可以用来分配任意大小的内存(仅仅受可用物理内存的限制)。用法可以和Win16下基本一样。</P>
  <P align=justify>Win32下保留这类函数保证了和Win16的兼容。</P>
  <P align=justify></P>
  <LI>C语言的标准内存分配函数 
  <P></P>
  <P align=justify>C语言的标准内存分配函数包括以下函数:</P>
  <P align=justify>malloc,calloc,realloc,free,等。</P>
  <P align=justify>这些函数最后都映射成堆API函数,所以,malloc分配的内存是不能移动的。这些函数的调式版本为</P>
  <P align=justify>malloc_dbg,calloc_dbg,realloc_dbg,free_dbg,等。</P>
  <P align=justify></P>
  <LI>Win32的虚拟内存分配函数 
  <P></P></LI></OL>
<P 
align=justify>虚拟内存API是其他API的基础。虚拟内存API以页为最小分配单位,X86上页长度为4KB,可以用GetSystemInfo函数提取页长度。虚拟内存分配函数包括以下函数:</P>
<UL>
  <P align=justify>
  <LI>LPVOID VirtualAlloc(LPVOID lpvAddress, 
  <P></P></LI></UL>
<DIR>
<P align=justify>DWORD cbSize,</P>
<P align=justify>DWORD fdwAllocationType,</P>
<P align=justify>DWORD fdwProtect);</P></DIR>
<P 
align=justify>该函数用来分配一定范围的虚拟页。参数1指定起始地址;参数2指定分配内存的长度;参数3指定分配方式,取值MEM_COMMINT或者MEM_RESERVE;参数4指定控制访问本次分配的内存的标识,取值为PAGE_READONLY、PAGE_READWRITE或者PAGE_NOACCESS。</P>
<UL>
  <P align=justify>
  <LI>LPVOID VirtualAllocEx(HANDLE process, 
  <P></P></LI></UL>
<DIR>
<P align=justify>LPVOID lpvAddress,</P>
<P align=justify>DWORD cbSize,</P>
<P align=justify>DWORD fdwAllocationType,</P>
<P align=justify>DWORD fdwProtect);</P></DIR>
<P 
align=justify>该函数功能类似于VirtualAlloc,但是允许指定进程process。VirtaulFree、VirtualProtect、VirtualQuery都有对应的扩展函数。</P>
<UL>
  <P align=justify>
  <LI>BOOL VirtualFree(LPVOID lpvAddress, 
  <P></P></LI></UL>
<DIR>
<P align=justify>DWORD dwSize,</P>
<P align=justify>DWORD dwFreeType);</P></DIR>
<P 
align=justify>该函数用来回收或者释放分配的虚拟内存。参数1指定希望回收或者释放内存的基地址;如果是回收,参数2可以指向虚拟地址范围内的任何地方,如果是释放,参数2必须是VirtualAlloc返回的地址;参数3指定是否释放或者回收内存,取值为MEM_DECOMMINT或者MEM_RELEASE。</P>
<UL>
  <P align=justify>
  <LI>BOOL VirtualProtect(LPVOID lpvAddress, 
  <P></P></LI></UL>
<DIR>
<P align=justify>DWORD cbSize,</P>
<P align=justify>DWORD fdwNewProtect,</P>
<P align=justify>PDWORD pfdwOldProtect);</P></DIR>
<P 
align=justify>该函数用来把已经分配的页改变成保护页。参数1指定分配页的基地址;参数2指定保护页的长度;参数3指定页的保护属性,取值PAGE_READ、PAGE_WRITE、PAGE_READWRITE等等;参数4用来返回原来的保护属性。</P>
<UL>
  <P align=justify>
  <LI>DWORD VirtualQuery(LPCVOID lpAddress, 
  <P></P></LI></UL>
<DIR>
<P align=justify>PMEMORY_BASIC_INFORMATION lpBuffer,</P>
<P align=justify>DWORD dwLength</P>
<P align=justify>);</P></DIR>
<P 
align=justify>该函数用来查询内存中指定页的特性。参数1指向希望查询的虚拟地址;参数2是指向内存基本信息结构的指针;参数3指定查询的长度。</P>
<P align=justify></P>
<UL>
  <P align=justify>
  <LI>BOOL VirtualLock(LPVOID lpAddress,DWORD dwSize); 
  <P></P></LI></UL>
<P align=justify>该函数用来锁定内存,锁定的内存页不能交换到页文件。参数1指定要锁定内存的起始地址;参数2指定锁定的长度。</P>
<UL>
  <P align=justify>
  <LI>BOOL VirtualUnLock(LPVOID lpAddress,DWORD dwSize); 
  <P></P></LI></UL>
<P align=justify>参数1指定要解锁的内存的起始地址;参数2指定要解锁的内存的长度。</P>
<OL>
  <OL>
    <OL>
      <P align=justify>
      <LI><A name=_Toc445889124></A><A name=_Toc445782527></A><A 
      name=_Toc452640986></A><A name=_Toc457299095></A><B>C++的new 和 
      delete操作符</B> 
      <P></P></LI></OL></OL></OL>
<P 
align=justify>MFC定义了两种作用范围的new和delete操作符。对于new,不论哪种,参数1类型必须是size_t,且返回void类型指针。</P>
<OL>
  <P align=justify>
  <LI>全局范围内的new和delete操作符 
  <P></P>
  <P align=justify>原型如下:</P>
  <P align=justify>void _cdecl ::operator new(size_t nSize);</P>
  <P align=justify>void __cdecl operator delete(void* p);</P>
  <P align=justify>调试版本:</P>
  <P align=justify>void* __cdecl operator new(size_t nSize, int nType, </P>
  <P align=justify>LPCSTR lpszFileName, int nLine)</P>
  <P align=justify></P>
  <LI>类定义的new和delete操作符 
  <P></P></LI></OL>
<P align=justify>原型如下:</P>
<P align=justify>void* PASCAL classname::operator new(size_t nSize);</P>
<P align=justify>void PASCAL classname::operator delete(void* p);</P>
<P align=justify>类的operator new操作符是类的静态成员函数,对该类的对象来说将覆盖全局的operator 
new。全局的operator new用来给内部类型对象(如int)、没有定义operator new操作符的类的对象分配内存。</P>
<P align=justify>new操作符被映射成malloc或者malloc_dbg,delete被映射成free或者free_dbg。</P>
<OL>
  <OL>
    <P align=justify>
    <LI><A name=_Toc445889125></A><A name=_Toc445782528></A><A 
    name=_Toc452640987></A><A name=_Toc457299096></A><B>调试手段</B> 
    <P></P>
    <P align=justify>MFC应用程序可以使用C运行库的调试手段,也可以使用MFC提供的调试手段。两种调试手段分别论述如下。</P>
    <OL>
      <P align=justify>
      <LI><A name=_Toc445889126></A><A name=_Toc445782529></A><A 
      name=_Toc452640988></A><A name=_Toc457299097></A><B>C运行库提供和支持的调试功能</B> 
      <P></P></LI></OL></LI></OL></OL>
<P align=justify>C运行库提供和支持的调试功能如下:</P>
<OL>
  <P align=justify>
  <LI>调试信息报告函数 
  <P></P>
  <P align=justify>用来报告应用程序的调试版本运行时的警告和出错信息。包括:</P>
  <P align=justify>_CrtDbgReport 用来报告调试信息;</P>
  <P align=justify>_CrtSetReportMode 设置是否警告、出错或者断言信息;</P>
  <P align=justify>_CrtSetReportFile 设置是否把调试信息写入到一个文件。</P>
  <P align=justify></P>
  <LI>条件验证或者断言宏: 
  <P></P>
  <P align=justify>断言宏主要有:</P>
  <P align=justify>assert 检验某个条件是否满足,不满足终止程序执行。</P>
  <P align=justify>验证函数主要有:</P>
  <P align=justify>_CrtIsValidHeapPointer 验证某个指针是否在本地堆中;</P>
  <P align=justify>_CrtIsValidPointer 验证指定范围的内存是否可以读写;</P>
  <P align=justify>_CrtIsMemoryBlock 验证某个内存块是否在本地堆中。</P>
  <P align=justify></P>
  <LI>内存(堆)调试: 
  <P></P></LI></OL>
<DIR>
<P align=justify>malloc_dbg 
分配内存时保存有关内存分配的信息,如在什么文件、哪一行分配的内存等。有一系列用来提供内存诊断的函数:</P></DIR>
<P align=justify><B>_</B>CrtMemCheckpoint 保存内存快照在一个_CrtMemState结构中;</P>
<P align=justify>_CrtMemDifference 比较两个_CrtMemState;</P>
<P align=justify>_CrtMemDumpStatistics 转储输出一_CrtMemState结构的内容;</P>
<P align=justify>_CrtMemDumpAllObjectsSince 输出上次快照或程序开始执行以来在堆中分配的所有对象的信息;</P>
<P align=justify>_CrtDumpMemoryLeaks 检测程序执行以来的内存漏洞,如果有漏洞则输出所有分配的对象。</P>
<OL>
  <OL>
    <OL>
      <P align=justify>
      <LI><A name=_Toc445889127></A><A name=_Toc445782530></A><A 
      name=_Toc452640989></A><A name=_Toc457299098></A><B>MFC提供的调试手段</B> 
      <P></P></LI></OL></OL></OL>
<P align=justify>MFC在C运行库提供和支持的调试功能基础上,设计了一些类、函数等来协助调试。</P>
<OL>
  <P align=justify>
  <LI>MFC的TRACE、ASSERT 
  <P></P>
  <P align=justify>ASSERT</P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -