VC6.0调试入门与提高(一)_vc60调试入门与提高一-程序员宅基地

技术标签: 制造  VC MFC  工具  mfc  程序开发  delete  tools  

 

前沿

 

作者:化凡

QQ 371691096

20094

 

说明:文章的名字可能取的比较大,毕竟本人能力有限,掌握的知识比较肤浅,写出的东西可能没有多大的价值。但是看到一些初学者经常问一些太过简单的问题,我终于忍不住想写点什么。通过与很多初学者交流,我发现他们共有的一个弱点是不会调试。很多人根本不知道调试是怎么回事。其实很多问题,只要会调试都能自己解决。

       签于此,我就根据自己在程序开发中积累的经验写一点关于VC6.0下调试的基本知识和技巧,希望对初学者有点帮助。由于本人的能力有限,文章中可能会有很多不周到之处,希望读者谅解,同时提出批评和指正,以达到共同提高的目的。

测试程序:为了有个直观的认识和方便学习,我将通过具体的实例程序进行介绍。本文选取的是基于MFC的单文档程序,程序名称为MyDebug。文章会列出本人所了解的错误和调试技术。

常见错误:初始化错误、缺少头文件、少lib(链接错误)、少dll(运行错误)、类型不匹配(编译错误)、断言错误等等(以后会继续扩充)。

 

 

 

正文

一、调试工具栏介绍

11 Debug工具栏

当进入调试状态时,工具栏上会出现如下的工具条。      

1

 

如果不出现上述工具条,可以进行如下操作调出该工具条。

1)选择菜单栏的Tools菜单项,出现如下窗口

2

 

2)选择Toolbars选项卡,如上图,然后在Debug打上勾,就ok了。

12右键弹出调试菜单

3

 

       如上图,进入调试状态后,在工具栏的空白处点击右键会弹出上图菜单。在调试的时候重点介绍椭圆区域内的几个选项。

       可能很多人不明白,不是说调试嘛,干嘛要说这些!呵呵,其实我也觉得没必要,但是我又担心对于初学者来说,这些可能会很麻烦,所以还是先简单介绍一下。先给读者一个整体的认知,做到心中有数。至于上述选项有何功能,本文后续内容会逐一到来。

二、开始第一个调试工作

2.1 断点的设置

       进行调试的第一步就是要设置断点。如何设置断点呢?打开一个VC程序,在工具栏中可以到这样的工具条4。如果没有可以这样操作Tools->Customize->Toolbars标签,然后选择Build MiniBar,这样就ok了。

       设置断点:把光标放在程序的某一行如放在CMyDebug的构造函数中,按F9或者鼠标左键单击手型按钮,设置后如下图:

5

2.2 调试运行

       设置断点后就可以调试运行了。按F56就进入调试运行状态。如果按照上述操作,可以到程序停在断点处。如下图:

7

2.3 停止调试

       停止调试的方法有很多,如点击编译选项或Debug工具栏上的停止调试选项8

2.4 小结

       好了到此可以给出一个小结,可能读者会觉得不齿,这说的是什么啊,到这就小结了?根本什么内容都没说嘛!确实还没说到重点,但是在这里给出一个小结,我觉得是有必要的。因为本小结已经讲述了一个完整的调试的基本步骤。

三、常见错误及调试技术

       好了,现在开始说些实用的东西。到此,假设读取已经了解调试的基本知识和步骤。下面的内容可能会忽略一些细节,主要讲解常见的错误以及调试技术。

3.1 开始运行错误

       很多程序编译和连接的时候都没有问题,但是只要运行就会出错,而且往往还找不到错误在什么地方,即使用调试运行,也不知道错误在什么地方,因为调试运行时,光标会停在一些看不懂的代码里。对与这类的错误,其实很好调试。这类错误,本人称之为开始运行错误或初始化错误。

       这类错误一般发生在初始化函数里或构造函数里。调试这种错误需要用到第一章第二小结介绍的“右键弹出调试菜单”的Call Stack选项。

       为了说明问题,我会故意在程序中制造错误,然后说明如何通过调试的手段找到这个错误。

3.1.1 错误设置

       为了制造一个开始运行错误,可以在CMyDebugView的构造函数添加如下代码(注意:先不加任何断点):

CMyDebugView::CMyDebugView()

{

       CString str="abcd";

       char a=str[5];

}

3.1.2 调试运行

       按如上方式书写代码后,调试运行(直接运行肯定是不行的)会出现如下结果:

9

 

       对于初学者来说,一看到这个问题,可能就懵了!这是为什么呢!其实很多问题都会造成这样的错误。我们先不管这些了,接下来点击重试(R)按钮(点击其他两个也可以 ,但是找不到错误,所以还是按照我说的做吧!^_^)。点击该按钮后会出现如下结果:

10

 

       这是什么代码?我可没写过这样的代码啊!确实,我们并没有写过这样的代码,但是这样的代码是从哪里来的呢?这个不要担心,我们可以先不管它。如果想知道,我可以解释一下。对于这段代码,是MFC自己提供的,是CString的一个成员函数。

       好了,遇到这个问题,我们怎么解决呢?既然这段不是我们的,那我们想办法找到我们自己写的代码。好!下面教你如何找到自己的代码。

3.1.3 找到自己的代码。

       还觉得刚才说的Call Stack选项吧!对,就是用它。在工具栏空白处右击会弹出一个快捷菜单,如下左图:

11  12

左图                                                                                        右图        

                     

选择Call Stack,点击鼠标左键,出现上右图。上右图里会出现很多函数名。其中有很多是我们认识的,也有很多是我们不认识的。从光标出开始往下找,找到第一个我们认识的函数名,如上图红色椭圆标示的函数名,双击该函数,光标会跳转到改函数的函数体,有经验的读者会发现,光标所在的位置,往往就是错误发生的位置。好了,双击函数名会得到如下图:

12.5

 

       好了,到了这一步我们就不难发现错误了,仔细看一下,str的长度为4,而str[5]显然超过字符串的长度,当然会出现错误。

       注意:往往“开始运行错误”没有这么简单,但是原理就是这样的,这需要读者自己多多练习。好了,第一个错误就说到这里。

3.2 运行结束错误

       顾名思义,运行结束错误,是当程序运行结束后关闭程序时出现的错误。可能很多读者会说,程序都运行完了,出现错误就出现呗,反正不影响程序的运行。其实这种观点是错误的!一个完整的程序是不允许出现这样问题的!即便有些时候不影响程序的运行,但总会让人觉得讨厌。

       这种类型的错误和3.1节介绍的错误很相近,一个是在程序运行时出错,一个是在程序结束时出错,这两种错误都让人摸不到头脑。但是,我告诉你,这两种错误其实是最好调试的。“运行结束错误”一般发生在析构函数或资源释放的函数里。通常情况下都是内存释放时出现错误。

3.2.1 错误设置

       这类错误常出现在析构函数中,一般是由释放内存空间造成的,因此,本节先构造一个简单的内存空间释放错误。其它类似的资源释放错误有可能出现在程序的其他地方,不一定都在析构函数里,读者要学会变通。

CMyDebugView::~CMyDebugView()

{

       int row=10,col=20;;//动态数组的函数和 列数

       int **array=NULL;//动态整型数组指针

       //动态开辟一个二维数组

       array = new int *[row];

       for (int i=0;i<row;i++)

       {

              array[i]=new int[col];

       }

       //开辟空间一定要记着释放空间

       for (i=0;i<row;i++)

       {

              delete []array[i];

       }

       delete []array;

       //资源释放后,试图访问该资源

       int b=array[0][0];

}

3.2.2 调试程序

       正常运行程序一点都没有问题,但是当关闭的时候就会出现问题了。遇到问题,首先想到的是调试!调试运行程序,然后点关闭程序,这时我们会遇到如下的错误:

13

       错误很奇怪,不知道是怎么回事,没关系,点击确定。光标会自动跳到如下左图所示位置。

14    15

 左图(错误位置)                                          右图(变量值查看)

 

既然光标跳到此处,说明此处肯定存在问题。为了便于观察,我们把array这个变量拖放到“Watch”这个窗口里,如上右图。可以看到红色区域的值有点不正常(有经验的程序员能看出来)。这样就确定确实是这条语句出错了,再仔细分析,原来是array的空间已经释放,而程序还试图访问这个空间,显然这是不对的。

3.2.3 变量查看窗口

上面的步骤中提到了“Watch窗口”,该窗口是做什么用的呢?好,在这里有必要做个说明。“Watch窗口”是用来在调试状态下,查看变量值的,如果关注某个变量或数组的值,可以把这个变量名直接拖放到Watch窗口里,就可以查看该变量的值。通常包含几个子窗口,如下:

16  17

       Watch窗口”                                    Context窗口             

 

Watch窗口”是在调试状态下才可以看到,如果没有,在调试状态下,鼠标右击工具栏,会出现如下菜单:

 

18

 

相信这个菜单应该不陌生了吧。点击红色区域就可以了。既然提到了“Watch窗口”,理所当然地要提“Context窗口”,该窗口用于显示上下文变量。关于这个窗口的使用,读者可以自己琢磨一下。如果调试状态下没有这个窗口,操作类似上面的方法,唯一的区别就是点击上图中的绿色区域选项。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xuer_07/article/details/4052666

智能推荐

gdb图形化工具gdbgui的安装_gdbgui 怎么安装运行-程序员宅基地

文章浏览阅读5k次,点赞2次,收藏3次。系统环境:python环境:下面进行安装:(均以root用户安装)1.安装pipxcurl https://raw.githubusercontent.com/cs01/pipx/master/get-pipx.py | python3出问题了,提示安装方法失效了。打开链接:https://github.com/pipxproject/pipx找到以下部分:注意:这里有个坑,我们..._gdbgui 怎么安装运行

二叉树的层序遍历算法_编写算法,实现二叉树的层序遍历-程序员宅基地

文章浏览阅读291次。二叉树的层序遍历算法是一种按照层级顺序访问节点的方法,它利用队列的先进先出特性来实现。通过遍历每一层的节点,并将其子节点入队,我们可以按照层级顺序获取二叉树中的节点值。在这篇文章中,我们将介绍如何实现二叉树的层序遍历算法,并给出相应的源代码。在每一次迭代中,我们首先取出队首节点,访问它,并将它的左右子节点(如果存在)依次入队。如果该节点存在右子节点,则将右子节点入队。变量记录当前层的节点数量,这是为了在内层循环中准确地遍历当前层的节点。以上示例中,我们创建了一个二叉树,并使用层序遍历算法对其进行遍历。_编写算法,实现二叉树的层序遍历

linux usb虚拟网卡(NCM)_linux usb ncm-程序员宅基地

文章浏览阅读6.6k次。1. kernel config<M>USB Gadget precomposed configurations<M>Ethernet Gadget (with CDC Ethernet support) <M>Network Control Model (NCM) support2. build modulesmake ARCH=arm64 CROSS_COMPILE=aar..._linux usb ncm

Struts 应用转移到 Struts 2-程序员宅基地

文章浏览阅读1.9k次。 翻译:SpringSide团队 转载请注明出处。有很多人都很熟悉 Struts, 无论是从项目中直接获得的实战经验还是从书中了解到的。我们这一系列文章,将通过一个由 Stuts 转移到 Struts2 简单的例子向大家展现Struts2的所有特征。 在我们开始这个例子之前,你需要去知道一点 Struts2的背景知识。 在第一部分的文章中,我们将介绍Struts2与Struts的核心

在Windows平台上安装MRTG流量监控软件_mrtg 下载-程序员宅基地

文章浏览阅读188次。打开MRTG软件包中的"MRTG.cfg"文件,该文件是MRTG的主配置文件。打开MRTG软件包中的"MRTG.cfg"文件,该文件是MRTG的主配置文件。确保将命令中的"C:\MRTG"替换为你的MRTG安装目录和配置文件路径,"community"替换为你的SNMP团体字符串,"device_ip"替换为目标设备的IP地址。确保将命令中的"C:\MRTG"替换为你的MRTG安装目录和配置文件路径,"community"替换为你的SNMP团体字符串,"device_ip"替换为目标设备的IP地址。_mrtg 下载

随便推点

Spring4MVC 基本配置_springmvc4 静态配置-程序员宅基地

文章浏览阅读898次。SpringMVC的定制配置需要继承一个WebMvcConfigurerAdapter类,重写这个类的方法,完成常用配置。@Configuration@EnableWebMvc@ComponentScan("com.netant.spring4")public class WebMvcConfig extends WebMvcConfigurerAdapter{视图解析器 /** 视图解_springmvc4 静态配置

第三十二节 java学习 —— Applet_java applet是在哪学的-程序员宅基地

文章浏览阅读324次。1》Applet的定义applet是java语言编写的,无法独立运行,但是可以镶嵌到网页中执行。它扩展了传统的编程结构和方法,可以通过互联网发布到任何具有java编译环境的浏览的个体计算机上。 2》Applet用途用户可以静态显示Applet,像显示一副图片或一段文本一样;Applet可以是一个动态交互过程,用户输入简单的数据产生相应的响应。3》Applet编写的格式在编写_java applet是在哪学的

zabbix_server 3.0 安装-程序员宅基地

文章浏览阅读57次。2019独角兽企业重金招聘Python工程师标准>>> ..._zabbix server 3.0安装

OpenCV图像梯度_opencv 计算梯度图像-程序员宅基地

文章浏览阅读1.7k次。目标在本章中,我们将学习:寻找图像梯度、边缘等 我们将看到以下职能:cv2.sobel(), cv2.scharr(), cv2.Laplacian()等理论OpenCV提供三种类型的梯度滤波器或高通滤波器,Sobel、Scharr和Laplacian.我们会看到他们中的每一个。1.Sobel和Scharr衍生物¶Sobel算子是一种联合高斯平滑加微分运算,具有更强的..._opencv 计算梯度图像

flutter 聊天界面+表情图片_flutter表情包插件-程序员宅基地

文章浏览阅读2.6k次。网上找了找 零零碎碎有一些文章 没找到一个整体的 自己做完记录一下 防止忘了大体就是这样聊天气泡用的是https://blog.csdn.net/oterminator12/article/details/105790961这个文章看到的然后表情用的是https://blog.csdn.net/qq_36676433/article/details/104756685这个文章看到的整体结构及底部输入/表情选择部分body下的结构主要为最外层Column,然后聊天部分用F..._flutter表情包插件

win10应用:便签 商店 xbox等打不开,报错0x800704cf_xbox0x800704cf错误代码-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏2次。登录便签,一直报错:执行此操作需要Internet,0x800704cf。笔者网络是没有问题的,其它程序可以正常访问。解决方法关闭代理1.Win+R打开运行,输入 inetcpl.cpl 打开internet选项界面2.切换到[连接]选项,点击局域网设置。红色框选处的两个勾取消。笔者上述配置后即可解决问题。如若还不能解决,试试下面这个方法设置DNS服务器地址,首选设置为4.2.2.1 备用设置为4.2.2.2..._xbox0x800704cf错误代码