您现在的位置是:首页 > 正文

VS2019实用调试技巧

2024-04-01 00:30:13阅读 1

1.debug和release的区别

VS集成开发环境上方有一个选项为Debug,表示这是代码的Debug版本,可以将其改为Release,表示这是代码的Release版本,那么Debug版本和Release版本有什么区别吗?

在这里插入图片描述
在这里插入图片描述

Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。

Release 称为发布版本,编译器对我们写的代码进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用,Release版本不能调试。

例:请看下面代码:

#include <stdio.h>
int main()
{
  int i = 0;
  int arr[10] = {0};
  for(i=0; i<=12; i++)
 {
    arr[i] = 0;
    printf("hehe\n");
 }
  return 0;
}

Debug版本下运行,该程序会出现死循环,即无限输出hehe,这是为什么呢?

i和arr都是局部变量,局部变量是存放在栈区上了,栈区内存的使用是先使用高地址处的空间,再使用低地址处的空间,数组随着下标的增长,地址由低到高变化,那么局部变量i和arr在栈区上的内存分配大致如下:
在这里插入图片描述

在vs2019环境下,变量i和arr相差两个整型,不同环境可能不一样,现在知道了局部变量i和arr的内存分配情况,我们先回归到代码。

由代码可知,从arr[10]开始越界访问,虽然对于程序而言arr[10]不存在,属于越界访问,但是对于实际内存而言,arr[10]就是arr[9]后面的一个位置,是真实存在的,因此可以将arr[10]赋值为0,同时也可以将arr[11]赋值为0,但是当访问到arr[12]的时候,由上面的内存分配图我们可以知道arr[12]实际上就是i,将arr[12]赋值为0,实际上就是将i赋值为0,因此i满足for循环条件,又会进入到下一轮循环,当i==12,再次访问到arr[12],将arr[12]赋值为0时,实际上又是将i赋值为0,又会进入下一轮的循环,因此这样下去就是无限死循环输出hehe。

那么在Release版本下,代码是怎么运行的呢?

在这里插入图片描述
如图所示在Release版本下,只输出了13次hehe,程序没有出现死循环,这是因为编译器对程序进行了优化:

由于Release版本无法进行调试,因此这里我们手动输出局部变量i和arr的地址:
在这里插入图片描述
前面说过局部变量存放在栈区,栈区的内存是从高地址向低地址使用的,因此变量i的地址应该大于arr的地址,可是由上图可知,变量i的地址小于arr的地址,这就是Release版本的优化,我们可以大致画出优化后的栈区内存分配图:
在这里插入图片描述
画出内存分配图后,我们可以更加清晰地了解到Releas版本对代码的优化,Release版本中,变量内存开辟的顺序发生了变化,先在高地址处开辟数组的空间,然后在低地址处开辟变量i的内存空间,这样即便数组越界访问,也不会影响到变量i的值,也就不会出现Debug版本死循环的情况。

由此可见Release版本的确会对代码进行优化,不过这种优化是底层的优化,比如这里对内存空间的开辟顺序进行了优化,而且这种优化并不会改变你的代码。

2.调试

首先要注意的是,调试只有在Debug版本下才能进行:
在这里插入图片描述

(1)调试最常使用的几个快捷键

F5:
F5向后执行代码,跳到下一个逻辑上的断点。

F9:
创建断点和取消断点。
断点的重要作用:可以在程序的任意位置设置断点。这样就可以使得程序运行到断点的位置停止执行,继而开始调试,一步步执行下去。
F9和F5是配合使用的。

F10:
逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句,逐过程执行会直接执行完整的过程,不会逐个执行过程中的每条语句。

F11
逐语句,就是每次都执行一条语句,这个快捷键可以使我们的执行逻辑进入函数内部(这是最长用的)。

CTRL + F5
开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。

(2)用监视窗口查看临时变量的值

监视窗口的打开过程如下:
在这里插入图片描述
打开监视窗口后,我们可以添加要监视的变量:
在这里插入图片描述
如图所示,我正在监视变量i和数组arr的信息:
在这里插入图片描述

(3)查看内存信息

打开内存窗口的过程如下:
在这里插入图片描述打开内存窗口后,我们查看数组arr的内存信息:
在这里插入图片描述
如图所示,输入arr即数组首元素的地址,然后就可以在下面看到数组每个元素的地址以及每个元素在内存中被初始化为0。

(4)查看调用堆栈

打开调用堆栈窗口过程:
在这里插入图片描述

在这里插入图片描述
在main函数处设置断点后,然后使用F11逐语句执行,就会进入调用函数内部逐条执行语句,通过调用堆栈,可以清晰地反应函数的调用关系以及当前调用所处的位置,比如从上面的调用堆栈中,我们可以看到当前调用所处位置是text2函数。调用关系是,main函数调用text,text函数调用text1,text1函数调用text2。

(5)查看汇编信息

在调试开始之后,有两种方式转到汇编:
(1)第一种方式:右击鼠标,选择【转到反汇编】:
在这里插入图片描述(2)通过调试窗口选择反汇编:
在这里插入图片描述

(6)查看寄存器信息

在这里插入图片描述
可以查看当前运行环境的寄存器的使用信息。

3.如何写出易于调试/好的代码

优秀的代码:

  1. 代码运行正常
  2. bug很少
  3. 效率高
  4. 可读性高
  5. 可维护性高
  6. 注释清晰
  7. 文档齐全

常见的coding技巧:

  1. 使用assert
  2. 尽量使用const
  3. 养成良好的编码风格
  4. 添加必要的注释
  5. 避免编码的陷阱。

4.编程中常见错误

  • 编译型错误:都是语法错误引起的,直接看错误提示信息(双击),解决问题。或者凭借经验就可以搞定。相对来说简单。
  • 链接型错误:看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是标识符名不存在或者拼写错误。
  • 运行时错误:借助调试,逐步定位问题。最难搞。

网站文章

  • dependency walker工具简介及使用

    dependency walker工具简介及使用

    dependency walker工具简介及使用

    2024-04-01 00:30:06
  • django中使用celery做异步任务、定时任务

    django中使用celery做异步任务、定时任务

    一、celery架构图 生产者消费者模型 调度方法 二、配置使用 celery很容易集成到Django框架中,当然如果想要实现定时任务的话还需要安装django-celery-beta插件,后面会说明...

    2024-04-01 00:29:58
  • 蜂鸟E203开发环境准备工作

    蜂鸟E203开发环境准备工作

    蜂鸟E203开发环境准备工作WindowsWindows工具“NucleiStudio”的快速上手Windows工具“Eclipse”的快速上手Linux安装VMware,安装Ubuntu18.04u...

    2024-04-01 00:29:36
  • Android 共存debug release版, 并设置不同名字

    一部手机上同时安装app的debug版和release版,并显示不同名字 build.gradle buildTypes { debug { applicationIdSuffix &quot;.debug&quot; resValue &quot;string&quot;, &quot;app_name&quot;, &quot;@string/app_name_debug&quot; ...

    2024-04-01 00:29:28
  • 神经网络向量化实现

    神经网络向量化实现

    矢量化编程 当使用学习算法时,一段更快的代码通常意味着项目进展更快。例如,如果你的学习算法需要花费20分钟运行完成,这意味着你每个小时能“尝试”3个新主意。但是假如你的程序需要20个小时来运行,这意味着你一天只能“尝试”一个新主意,因为你需要花费这么长时间来等待程序的反馈。对于后者,假如你可以提升代码的效率让其只需要运行10个小时,那么你的效率差不多提升一倍。 矢量化编

    2024-04-01 00:29:21
  • 动态数据源切换 AbstractRoutingDataSource

    动态数据源切换 AbstractRoutingDataSource

    2024-04-01 00:28:57
  • 解决WebStorm中无法拉取自己项目的问题

    解决WebStorm中无法拉取自己项目的问题

    1.打开webstorm,然后点击(file->setting->github)2.输入自己的账号和密码这里如果电脑本地不是自己的账号,会报错解决方案:打开控制面板->用户账户->管理您的凭据,修改git用户名和密码3.配置你的git4.拉取git项目代码...

    2024-04-01 00:28:50
  • 山东师范大学2024年的计算机毕设题目大全50例

    最近要准备毕业设计了,不会选题,希望可以帮忙给一些毕业设计题目,我整整花了一周把之前做的答辩通过的毕业设计成品进行整理如下列表。

    2024-04-01 00:28:42
  • Windows10安装visual studio 2013

    https://wenku.baidu.com/view/6f1ba49955270722192ef7a8.html

    2024-04-01 00:28:37
  • LeetCode数据库题目汇总一(附答案)

    LeetCode数据库题目汇总一(附答案)

    表: `Queue````person_id 是这个表的主键。该表展示了所有等待电梯的人的信息。表中 person_id 和 turn 列将包含从 1 到 n 的所有数字,其中 n 是表中的行数。``...

    2024-04-01 00:28:12