编译器的实用调试技巧

news/2024/6/16 16:16:53 标签: 算法, c语言, 开发语言, 考研, vscode

目录

一. 什么是bug

二.调试的基本步骤

三.Debug和Release

四.常用快捷键 

注意:如果你的快捷键被系统占用,那么可以尝试用:FN+快捷键

F10和F11的区别 :

F5和F9配合使用 

五.如果要观察某个成员

六.断点的使用

F5和F9配合使用 

条件断点 

多个断点的情况

错误案例

原因是栈区分配内存时出现的重复

栈区的分配 

优化的好处


一. 什么是bug

        一个bug的故事:有说法认为,世界上第一个bug出现在1944年,当时的第一台通用自动计算机塔克一号诞生。在一次维护过程中,一位名叫格蕾丝·霍普的女性程序员发现并解决了计算机中的一个缺陷,这个缺陷是由于一只蛾子飞入计算机内部造成的。她使用了发夹将蛾子夹出,并在管理日志上记录了这次事件。此后,“Bug”这个词就被用来指代计算机程序中的错误。

二.调试的基本步骤

  1. 发现程序错误的存在
  2. 以隔离、消除等方式对错误进行定位
  3. 确定错误产生的原因
  4. 提出纠正错误的解决办法
  5. 对程序错误进行改正,重新调试

三.Debug和Release

  1. Debug:是调试版本:它包含调试信息,并且不做任何优化,便于程序员调试
  2. Release:发布版本:它是已经进行过调试和优化,使得程序代码大小和运行速度都是最优的,以便用户使用。测试人员测试的是发布版本。

四.常用快捷键 

注意:如果你的快捷键被系统占用,那么可以尝试用:FN+快捷键

  1. F5 :启动调试用来直接跳到下一个断点处
  2. F9:创建断点,和取消断点
    1. 断点的作用,可以在程序的任意位置添加断点,这样可以使得程序在任意位置停止执行,继而一步步执行下。
  3. F10:逐过程,通常用来处理一个过程,一个过程可以是一个函数调用,或者是一条语句
  4. F11:逐语句,就是每次都执行一条语句,但是这个快捷键,可以使我们执行逻辑进入函数内部(这是最常用的)。
  5. CTRL+F5:开始执行不调试,即不调试直接运行。

F10和F11的区别 :

F10是一次完成一个过程,一次执行一个函数,之间完成函数的内容,不进入函数

F11是逐语句,F11会进入函数一条语句一条语句的执行

F5和F9配合使用 

F9打完断点,会让程序在断电处停止调试,当程序员咋某段代码不想一直调试想一步到位。

可以在那个代码旁边打上断点,然后按F5,让程序一步执行到断点处。

五.如果要观察某个成员

如观察这个arr数组的变化,

首先用        F10执行到这个数组。

然后在调试窗口里找到监视

 可以在监视窗口里检查你想看的内容

六.断点的使用

F5和F9配合使用 

F9打完断点,会让程序在断电处停止调试,当程序员咋某段代码不想一直调试想一步到位。

可以在那个代码旁边打上断点,然后按F5,让程序一步执行到断点处。

条件断点 

如果程序员觉得是在循环中的某一个出现了问题,比如1000次的循环,我们认为是在500次出现了问题,那么我们一个一个循环的去执行太麻烦可以设置条件循环。右击断点,设置条件。

多个断点的情况

如果有多个断点,按F5首先来到第一个断点,注意:再按一次F5不会立刻到下一个断点,而是按F5会 进入循环执行第二次,在按执行第三次等等,直到当前循环逻辑执行完。在次按F5才会直接跳到下一个断点。

 

错误案例

下面这个代码,会出现死循环,按常理来说,越界访问应该是会崩溃的代码,但是我们发现它居然是死循环。

 我们调试发现,i在没有越界的范围时,i是正常++。

 越界之后arr【10】是随机值,正常情况这里应该会报异常错误

 

再次循环访问之后 ,arr居然被赋值为0;

 再次循环到终止条件12,这是我们发现循环变量i,居然由初始化为0,而且我们对循环变量 arr【12】的地址一样。这就会导致i重新进入循环。导致死循环

原因是栈区分配内存时出现的重复

 我们分析代码在栈区,里首先对 Int i =0;分配1个内存地址,然后对数组 arr【】分配10个内存地址。

栈区的分配 

栈区是从高地址低地址分配空间的。

数组是从低地址高地址分配空间的。

所以首先给 循环变量 i 分配空间12,然后给数组arr分配10个空间,然后数组依次向下分配。直到我们越界访问12时 循环变量i 与 arr【12】地址一样,这样我们再次越界访问时就会进入循环。 

由于在vs的编译器下,循环变量 i 的栈区和数组arr【】的战区之间恰好相隔2个空间。

如果是在gcc,i 与 arr之间空1个整型

如果在vc里,i 与 arr 之间没有空隙

 

优化的好处

 如果我们将Debug版本换成Release,之后我们看看优化后的版本。

我们发现Release优化之后,居然没有进入死循环。

我们打印地址之后发现

Release 居然 将 本应该在高地址的循环变量i,和低地址的arr数组,交换了。让 i 去了低地址,arr去了高地址。这样就arr无论越界多少次,都不会和循环变量i重叠。 

 


http://www.niftyadmin.cn/n/5365687.html

相关文章

Python 数据可视化:配色方案

1、引言 在这篇文章中,我们将研究Python的一些配色方案,主要是Seaborn库。这将采用 Python Notebook 格式,其中包括绘图的代码。 2、实验数据 首先导入必要的库: import pandas as pd import seaborn as sns import matplotlib…

ubuntu系统更改了/etc/fstab文件后无法进入系统,解决办法!

背景: ubuntu更改了/etc/fstab文件后,重启无法进入系统,比如设置硬盘自动挂载之类的。 说明: /etc/fstab是linux系统的文件系统表。 在进入系统前是通过检查此文件来加载相应的分区文件系统(被记录到本文件中的所有文…

公告2024

亲爱的朋友, 我写这封道歉信是为了向你们表达我对我的错误的深刻歉意和诚挚的歉意。我承认,我太久没有更新了,给大家带来了困扰和不便,对此我深感抱歉。 首先,我要向你们承认,我忽视了我的责任和承诺&…

【数据结构与算法】(7)基础数据结构之双端队列的链表实现、环形数组实现示例讲解

目录 2.6 双端队列1) 概述2) 链表实现3) 数组实现习题E01. 二叉树 Z 字层序遍历-Leetcode 103 2.6 双端队列 1) 概述 双端队列、队列、栈对比 定义特点队列一端删除(头)另一端添加(尾)First In First Out栈一端删除和添加&…

Java实现康复中心管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 普通用户模块2.2 护工模块2.3 管理员模块 三、系统展示四、核心代码4.1 查询康复护理4.2 新增康复训练4.3 查询房间4.4 查询来访4.5 新增用药 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的康复中…

Flutter 解决ExpansionTile上下分割线问题,以及title撑满问题

文章目录 前言一、解决上下分割线问题二、使ExpansionTile的title撑满总结 前言 最近在做flutter项目,其中的一个功能用到了ExpansionTile的效果,奈何我们的设计师要求很高,展开的时候不能有上下一根线,而且我们是不需要展开的按…

algo-桶排序

桶排序 桶排序是一种分布排序,将元素数组分到多个桶内,然后每个桶再分别进行排序。 其计算复杂度取决于对桶内排序所用算法、使用桶数量以及输入均匀度。 主要流程如下 建立空桶数组将原始数组发布到各桶中对非空桶进行排序按照顺序从非空桶里面收集…

Linux编译工具 - addr2line工具使用培训 - ARM64架构

addr2line工具使用培训 - ARM64架构 技术背景 addr2line是一个在Linux环境下,用于将地址映射到文件名和行号的工具,主要应用于程序的调试过程中,帮助开发者定位问题发生的源代码位置。特别在ARM64架构的系统上,它能够有效地处理…