认识bug和调试
百度百科中这样解释bug.bug本意是“昆⾍”或“⾍⼦”,现在⼀般是指在电脑系统或程序中,隐藏着的⼀些未被发现的缺陷或问题,简称程序漏洞。
什么是调试(debug)呢?
当我们发现程序中出现问题时,找到并修复问题的过程就叫调试(debug)。
debug和release
在很多编译器上,我们都会看到有debug和release两个选项
debug通常称为调试版本,它包含调试信息,不做任何优化,便于程序员进行调试。
release称为发布版本。它往往是进行了各种优化,使得程序在速度和大小上都是最优的,以便用户使用
我们可以看到,同一段代码编译产生的可执行文件的大小,release版本明显更小。
vs调试快捷键
我使用的是vs2022,大家可以尽情尝试多种编译器的调试功能。
调试最常用的几个快捷键:
F9:创建断点和取消断点。
断点可以使程序任意停在想要停止的位置上。
F5:启动调试,直接跳到下一个断点,常常和F9配合使用。
F10:逐过程,一般用来处理一个过程,可以是一次函数调用,或是一条语句。
F11:逐语句,就是每次执行一条语句,但是这个快捷键可以使我们进入函数内部,如果想进入函数内部,就必须要使用F11,如果使用F10,直接完成函数调用。
CTRL+F5:开始执行不调试。使得程序直接运行起来
监视和内存观察
开始调试后,在菜单栏中【调试】->【窗⼝】->【监视】,打开任意⼀个监视窗⼝,输⼊想要观察的对
象就⾏。
打开监视窗⼝:
如果监视窗⼝看的不够仔细,也是可以观察变量在内存中的存储情况,还是在【调试】->【窗⼝】->【内存】
打开内存窗⼝:
调试举例
在VS2022、X86、Debug的环境下,编译器不做任何优化的话,下⾯代码执⾏的结果是啥?
#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
for(i=0; i<=12; i++)
{
arr[i] = 0;
printf("hehe\n");
}
return 0;
}
程序死循环了。让我们调试看看为什么。
1.栈区在内存中的使用习惯是从高地址向低地址使用,所以变量i的地址是较大的,而arr数组的地址整体是小于i的。
2.数组在内存中地址随着下标的增长而由低变高
那为什么i和arr数组之间恰好空出来2个整型的空间呢?这⾥确实是巧合,在不同的编译器下可能中间的空出的空间⼤⼩是不⼀样的,代码中这些变量内存的分配和地址分配是编译器指定的,所以的不同的编译器之间就有差异了。所以这个题⽬是和环境相关的
注意:栈区默认使用习惯是从高地址到低地址的,但是具体还是要看编译器的。比如在vs上切换到x64,这个顺寻就是相反的,在release版本中也是相反的
如有错误,恳请指正。