Windows C++编程的一些调试和检测方法

1、内存泄露的检测

     之前也用到了一些内存泄露的检测方法。知道大概的原理就是窜改内存分配的函数,在原始的分配基础(内存大小)上添加一些记录分配内存的信息,如文件、分配代码的行号。Windows编程中SDK、MFC提供的一些检测函数因为窜改的内存分配函数不同,所以检测的范围也不尽相同。

      因为之前的工作中使用MFC来实现系统界面,所以大部分代码都是链接的MFC库,而非Windows标准库,使用内存分配的函数是new,而非malloc,所以一般都用MFC提供的DEBUG_NEW来检测。一般会在文件的开头处使用下面的宏替换(这在MFC文件中非常常见):

       #ifdef _DEBUG
       #define new DEBUG_NEW
       #undef THIS_FILE
       static char THIS_FILE[] = __FILE__;
      #endif

这样在程序中使用new就会被DEBUG_NEW代替,DEBUG_NEW重载了new,所以在程序结束时,检测分配链表是否为空,非空则打印出相应的泄露代码行。

在afx.h中,定义DEBUG_NEW:

// Memory tracking allocation
void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
#define DEBUG_NEW new(THIS_FILE, __LINE__)

注意的是,此处DEBUG_NEW 仅仅只是替换new,所以只对new的内存分配具有作用,不能检测malloc分配的内存。另外,DEBUG_NEW替换了new,重载了函数,对那些本身就重载了new的类会有影响,使其不能正确的调用合适的new函数,发生错误,使用时也应格外小心这一点。

     以前虽然知道Windows提供了一些CRT的DEBUG方法类检测内存泄露,但一直没有使用过,前段时间找工作时,有被人问到,最近工作中看到公司的一些原来的代码中也有所使用。

      #ifdef _DEBUG
                _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
      #endif 

     

具体参考MSDN:

Call _CrtSetDbgFlag with newFlag equal to _CRTDBG_REPORT_FLAG to obtain the current _crtDbgFlag state

然后设置_CRTDBG_LEAK_CHECK_DF,这样就可以检测内存泄露问题了。

使用注意,需要加载头文件#include <crtdbg.h>,这样可以对malloc和new分配的内存同时检测。

 

2、特殊宏

     宏的使用可以帮助有效定位,错误发生的位置,MSVC中一般在Output窗口中输出文件名(代码行),双击该条目即可定位。

一般可写为TRACE(".......%s(%d)", __FILE__, __LINE__);

之前转载的文章《C/C++语言宏定义技巧》中有提到过这些宏(如_ L I N E _ 、_ F I L E _ 、_ D A T E _ 、_ T I M E _ 、_ S T D C _ ),具体可翻阅相关编译器资料,今天提到一个新的宏__FUNCTION__来获取函数名,据说VC6不支持,未尝试过,使用时应该注意编译器的版本和支持情况。

 

 3、NT服务程序调试

     之前一直没有写过NT服务的后台程序,最近负责查看一个NT服务程序,所以需要调试。在自己没有想到办法的时候,只能求助于MSDN和网络。网络搜索还是比较快捷的,抄在下面:

调试 Windows 服务应用程序

http://msdn.microsoft.com/en-us/aa984342(zh-cn,VS.71).aspx

  1. 安装您的服务。有关更多信息,请参见安装和卸载服务
  2. 可从服务控制管理器、“服务器资源管理器”或代码启动服务。有关更多信息,请参见启动服务
  3. 在 Visual Studio 中,从“调试”菜单中选择“进程”。

    出现“进程”对话框。

  4. 单击“显示系统进程”。
  5. 在“可用进程”区域内单击服务的进程,然后单击“附加”。
    提示   此进程将与服务的可执行文件同名。

    出现“附加到进程”对话框。

  6. 选择任意适当选项,然后单击“确定”关闭对话框。
    注意   您现在已处于调试模式。
  7. 设置要在代码中使用的任意断点。
  8. 访问服务控制管理器并操纵您的服务,并发送停止、暂停和继续命令以命中您的断点。有关运行服务控制管理器的更多信息,请参见启动服务

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值