VS的实用调试技巧(解决Bug)

张开发
2026/4/7 11:12:35 15 分钟阅读

分享文章

VS的实用调试技巧(解决Bug)
目录一Debug和Release二VS调试的快捷键三监视和内存观察1监视2内存四编程常见错误类型1编译型错误2链接型错误3运行时错误五调试举例1死循环打印2一维数组传参函数内部监视数组3二维数组传参函数内部监视数组一Debug和Releasedebug指的是调试或者说消灭bug,在一个出错的程序中我们需要通过调试的方法来找到bug并解决它。在VS中有两种项目配置模式一种是debug另一种是releasedebug为调试版本包含调试信息不能自主优化适合程序员对代码直接进行调试。使用通常是程序员在日常写代码需要频繁调试时使用。release为发布版本代码是优化过的使得程序在代码大小和运行速度上都是最优的可以更好的给用户使用。使用当代码经过测试后可以给用户使用时就会调整为Release版本。release版本的程序比debug版本的内存小得多。二VS调试的快捷键调试前提首先VS的模式必须是Debug常用快捷键F9:创建断点和取消断点断点断点可以设置在程序的任何地方设置断点后可以是程序在想要停止的位置中止此时可利用其他快捷键F10,F11,观察代码的运行过程的细节。通常和F5联合使用。条件断点设置一个条件利用F5会直接执行到满足条件时的断点处例断点的使用设置断点可以直接配合F5跳过前面的代码直接跳转到需要调试的部分。一般针对有问题的部分设置断点直接跳转然后通过其他快捷键进行运行过程分析。也可以直接在函数内部设置断点。F5:开始调试如果不设置断点则会直接执行完整个程序。若设置断点则会直接跳转到断点处。存在多个断点时若再次按F5则可以跳转到下一个断点若断点在循环中则会直接执行完此次循环到下一层循环的此断点处。F10逐过程分析。一句一句代码进行分析但不能在调用函数部分进入函数分析会直接执行出函数调用的结果。F11: 逐语句分析。每次执行一个语句和F10十分类似不过可以在函数调用语句部分进入函数内部分析。CtrlF5:直接运行不调试。ShiftF5:直接退出调试。三监视和内存观察1监视监视窗口是用于实时查看和修改变量表达式值的调试工具。可以精准的追踪代码中变量的值的变化状态。使用开始调试后点击工具栏中的【调试】-【窗口】-【监视】之后打开任意一个监视窗口在名称中输入需要监视的对象。就可以查看输入对象的值和类型。2内存想要看变量在内存中的储存情况就可以开启调试然后在工具栏中选择【调试】-【窗口】-【内存】打开内存窗口后要输入查找变量的地址例如arr,i等等就可以找到变量的地址在列处选择列数一般设置为4列。最左边以0X开头的是十六进制的地址中间部分是十六进制的内容储存值最右边的是一些乱码暂时不考虑。四编程常见错误类型1编译型错误编译型错误都是语法上的错误例如漏掉了一些符号输入格式有问题这类问题出现时可以通过VS下方的错误列表找到根源双击错误信息也可以直接跳转至出错的地方或附近这类错误容易解决随着对代码语法的熟练错误会越来越少。2链接型错误这类错误通常是标识符名不存在拼写错误重复定义头文件未包含库未包含出现的错误一般是……未定义无法解析的外部符号等等3运行时错误代码的语法内容没有缺陷但是有逻辑上的漏洞和预期要实现的目标不符。此类问题需要一步一步分析不断缩小可能存在问题的范围通过调试分析理想和现实之间的差异进行更改达到要实现的目标。五调试举例1死循环打印在VS2022,Debug,x86的环境下该代码的运行结果为死循环的打印hehe调试分析前十次0~9通过监视i,arr可以发现在前十次i从0一步步变为9此时屏幕上已经有10个hehe11次到12次10~11当再次执行时i变为10循环一次后屏幕已打印了11个hehe此时监视arr[10]发现arr[10]的值也被改为‘0’接着执行当i为11时12个hehearr[11]也为‘0’。第13次12当再次执行i为12时进入循环执行完arr[i] 0语句后i变为了0此时查看‘’arr[12]也为0再次执行当再次执行时i和arr[12]同时变化。而arr[12]和i没有明确的相等关系i和arr[12]是否调用的是相同的空间通过i和arr[12]发现两者的内存一样。就说明i和arr[12]本质一样。当一开始就监视i和arr[12]是会发现i和arr[12]在一开始就会同时变化。说明i和arr[10]创建后i和arr[12],所占用的空间一致。但是我们有没有创建arr[12]只创建了arr[1]到arr[10].故可以推断当创建了i和arr后i就和arr[12]相等若后续不进行数组越界则不会发现arr[12]就等于i,也不会产生错误。那么是什么导致i和arr[12]的存储空间相同此后一直执行上述过程造成死循环的呢这一定和i和arr的内存开辟有关以下是i和arr在内存中的占用情况栈区内存的地址的使用习惯是从高地址到低地址故i的地址大于arr整体的地址而数组的中内容的地址则是随下标从低到高。i和arr中间有一定的空间当数组arr[]调用越界到i时此时的i与arr[]就是相等的或者更准确地说创建完arr[ j ]则arr[j2] 就是一定等于i,在此环境下只是正常情况下我们不会调用arr[j2]此类越界的内容。补充问题i和arr数组之间的空间一定为两个整形吗变量的内存分配和地址分配是由编译器决定的在不同的编译器中所空出的空间是不同的。这就是一直强调环境的原因。vc6.0中间是连续的gcc中间空一个整型。栈区的内存存储习惯也和编译器有关默认为先使用高地址在使用低地址例如在VS中的x64中使用顺序就是相反的在Release中使用的顺序也是相反的。2一维数组传参函数内部监视数组当数组传参时由于数组传的是第一个元素的地址所以在函数内部通过监视arr数组名的方式无法查看数组内所有元素的值。此时可以通过输入数组名n n为个数的方式查看数组内元素的值例3二维数组传参函数内部监视数组若只输入arr则只能查看第一行的内容表明二维数组传参只会传第一行的数据。此时通过数组名行数就可以监视数组内的所有数据总结调试是当代码没有按照我们的预期执行时要让代码回归我们预期的情况运行进行的错误排查。在调试时一定要知道我们预期所呈现结果这样才能有针对性的对代码进行医治。提升了调试的高效性和准确性。调试需要大量的练习才能加深对代码的理解以及分析问题的能力调试的多了就能看到问题的本质对程序的运行了如指掌。

更多文章