VS2019调试技巧
1. bug的由来
在几十年前的时候,那个时候只虫子爬到了当时的巨型计算机里,导致那台巨型计算出现了问题。而虫子的英文就是bug,bug这个词就由此诞生了。找bug也就是我们常见的调试,只有调试更快的找的bug。
2. windows环境调试介绍
注意:在vs2019中只有将环境学则为debug
才能调试
1. 常用快捷键
- F5
启动调试 - F9
在当前行打断,端点可以放在程序的任何位置,就可以让程序停止在你想停止的地方
- F10
逐个过程调试,调试的时候遇到函数会接着执行,并不会进入到函数内部,也就是看不到函数内部细节
- F11
逐语句,每按一次F11程序每执行一条语句,F11和F10的别是F11会**进入到函数内部
- ctrl + F5
直接执行程序不调试
2. 调试的时候查看程序当前信息
在开始调试后,可以用来观察变量的变化
观察内存变化
查看调用栈
甚至还可以转到反汇编
3. 经典题目
这段代码再vs2019的x86环境,devc++,Linux上都出现了死循环。
#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("hello\n");
}
return 0;
}
通过调试我们发现,当i=12的时候,arr[12]和变量i使用的是同一块地址,也就是arr[12]就是变量i。
每次到当i为12的时候都会把变量i赋值为0,就出现了死循环。
这是怎么一回事呢?
- 我们知道i和arr都是局部变量,而局部变量都是存放在内存存的栈区的。
- 而栈区内存的使用习惯:先试用高地址处的空间,再使用低地址的空间
- 而数组随着下标的增长地址是从低到高变化的
- 所以当数组在适当的越界的情况下就会导致数组的越界访问到循环变量i,就可能到死循环
- 也就是说arr[9]和变量i的地址相差了8个字节,所以就出现了越界访问导致了死循环
- 注意:不同的编译器它们之间相差的字节可能不一样,在vs2019的x86环境下是8个字节,而我在devC++上测试i等于11就出现了死循环,在Linux64位机器的CentOS7上也在等于11时就出现了死循环。
- 编译器忙着死循环就管不了越界哈哈。
4.Debug和Release
1.Debug版本:debug版本被称为调试版本,它包含调试信息,一般不会做任何优化,方便程序员调试
2.Release版本:release版本被称为发布版本,它一般都会对代码进行优化,在代码的大小和运行速度上往往都是最优的。方便用户去使用
继续来看上面那段代码,我们把环境切换成Release版本和Debug版本进行对比,发现就没有死循环了。那是因为Release版本进行了优化。
我们发现Release版本把变量i放到了arr数组的前面那块内存空间了,也就是地址比数组小,这样无论数组怎么越界就不会访问到i了
debug版本
Release版本
5. 断言
使用断言需要引入头文件#include <assert.h>
断言里的表达式为真什么都不发生,为假就会报错
来看一段代码
void prt(char* str)
{
assert(str != NULL);
printf("%s\n", str);
}
int main()
{
prt(NULL);
return 0;
}
当出入一个空指针就会触发断言报错
而如果是Releas版本,断言是会被优化掉的