VC调试技巧之一般技巧

编译器基本技巧: F10: 单步调试,按步执行程序,一般用来察看程序执行流程,如果程序程序从中断掉了,就可以用单步调试。F9: 设置断点,程序在执行到设置断点的地方就会停下。F5: 执行调试程序,Debug|Go。F11: 进入block内部进行调试。Ctrl+F5: 在使用的时候,执行调试程序,Debug|Execute。Ctrl+F7: 编译单个文件,而不编译所有文件,这样可以避免编译一些不必要的文件而增加编译时间。Clean: 清除工程Rebuild all : 删除之前产生的中间生成文件以后,重新编译整个工程Watch 窗口:将变量添加到watch窗口,并且可以查看变量值,但是不能察看函数的返回值,一般要看函数的返回值,应该将其保存在变量,然后进行察看。Call Stack: 调用函数栈,在call stack里面可以看到各级函数的调用关系,并且这样方便定位bug报错位置。Shift+F5: 取消调试过程。Ctrl+ B: 设置数据断点和位置断点。 位置断点:这是我们经常采用的办法,在我们要调试的代码行上设置一个断点,然后按F5或者F10进行调试,这种方法在非循环的代码block里面是可行的,但是如果在一个循环里面,那么就有点麻烦了,这样的话,你要多次地按F5,假如循环次数超过1000的话,想想看,不说你按F10来单步调试,就是按F5也要耗掉你不少体力.这里介绍一个方法:即断点的条件判断法.设置你要调试的代码行.用ctrl+b打开断点设置对话框,这样的话,我们就看到了一个location,我们可以在下面的breakpoints列表里选择我们所要调试的代码行,这样的话,在上面我们就可以在break at这个框里面看到我们刚才选择的代码行,接着在下面的condition按钮中选中,在"Enter the expression to be evaluated"这一项中输入一个表达式,这个表示只有在该表达式成立的情况下,这个断点才能被启动.当然如果是输入一个变量名的话,那么在这个变量被修改的时候,断点才能被启动.另外还有两项:"Enter the number of elements to watch in an array or structure" 以及"Enter the number of times to skip before stopping".在这里都可以设置一些选项,这些对于循环的block非常有用.第一项表明要输入某个数组或者结构中要观测的项目数,第二项表示在终止前要跳过的次数,显然在循环次数很多的情况下是很有用的,在这里我们可以设置他为循环的次数,这样的话,等所有信息都设置好以后,按F5以后,程序就会被中断,那么我们在"breakpoints"这里就可以看到一个信息"remaining xx"这表示说在循环进行100-xx+1项后就终止了,我们当然还可以采用"Enter the expression to be evaluated"这种方法,直接从值这个方面来获取信息,而不是从次数上获取信息.for (int i = 100;i >0;i--) { printf("%d",100/(i-5)); }这就是个例子来的.数据断点:就是我们开始说的"Enter the expression to be evaluated"这种方法,即在满足某个条件值时,断点才会启动.其实位置断点和数据断点是互补的,相对而言,数据断点更加适合于判断数据时候被修改这种的情况,而位置断点一般用在循环中,来说明程序执行的情况.在那个位置出错了,我们找到这个位置再去定位错误.另外还有一种方法:在callstack里面为某个函数设置断点,这样的话,就可以将函数调用从深度层次中返回.还有可以在调试状态下,在某个代码行A处单击右键菜单中选择set next statement这个项,这样的话,下次执行的代码行就是A了,而不是其它代码行,其实从字面意思就可以了解了.另外watch窗口也可以用来监视变量的值变化,很管用的,特别对于一些数组,结构之类的,你可以查看数组/结构里面所有元素的值情况,不过我们用完了就得删除我们选择的变量,因为下次使用的时候它们还会出现的. 打印log:可以通过输出函数打印相关信息,将log信息输出到屏幕,这些方法主要有:Prinf, cout, MessageBox, 以及OutputDebugString等。当然也可以将信息记录在文本里面供执行以后察看,用fopen之类的,将信息写入文件。 查找崩溃地址:可以采用dbghelp,具体信息可以到微软的官网上查找 也可以使用map 文件,这里有一篇介绍不错的文章。http://www.codeproject.com/KB/debug/mapfile.aspx 使用断言:断言可以帮助你更加检查数据的有效性,不过要注意的一点是,不要在断言里面使用函数,因为在非debug模式下面,比如release模式下面assert是无效的,要跳过去执行的。 使用异常:Try/catch/throw, 以及__try/__catch/__throw等 其他调试信息和相关编译器设置信息:http://ei.cs.vt.edu/~cs1205/c_debug/intro.htmlhttp://www.hermetic.ch/cfunlib/debug.htmhttp://www.gamedev.net/reference/articles/article1344.asp 编程习惯建议:多使用断言,assert对数据前驱和后继进行检查,使用防御编程,在函数入口,和函数出口处都进行数据检查。在申请内存或者分配空间的时候,要检查数据是否分配成功,如果没有分配成功的话,要做相关的处理。在声明变量的时候,最好也要进行初始化,防止没有经过初始化获得一些未知的数值。未初始化的内存区一般被0xcccccccc填充,已经释放掉内存的区域一般是0xcdcdcdcd.如果你试着访问一个数据值为0xcdcdcdcd的指针,那么意味着你已经在某个地方将该之珍释放掉了,如果是0xcccccccc,那么意味着该指针一直没有被分配空间。 (1)指针消亡了,并不表示它所指的内存会被自动释放。(摘自林博士的高质量C++编程) (2)内存被释放了,并不表示指针会消亡或者成了NULL指针。这里可以这样来理解:1)对于栈上的内存区域,那么在该指针离开了该作用域以后,就无效了,但是并不意味着该指针所占据的内存被自动释放了,相反,出现内存泄漏了。2)在释放内存以后,该指针仍旧未非空的,所以还要将之置空,避免出现野指针。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值