【C语言】VS实⽤调试技巧&(Debug和Release)监视&内存2

简介: 【C语言】VS实⽤调试技巧&(Debug和Release)监视&内存

【C语言】VS实⽤调试技巧&(Debug和Release)监视&内存1:https://developer.aliyun.com/article/1474243

2.1 内存

如果监视窗⼝看的不够仔细,也是可以观察变量在内存中的存储情况,还是在【调试】->【窗⼝】->

【内存】

打开内存窗⼝:

在打开内存窗⼝后,要在地址栏

输⼊:arr,&num,&c,这类地址,就能观察到该地址处的数据。

除此之外,在调试的窗⼝中还有:⾃动窗⼝,局部变量,反汇编、寄存器等窗⼝,⾃⾏验证使⽤⼀下。

接下来,让我们开始上代码展示,一起调试起来:

在VS2022、X86、Debug 的环境下,编译器不做任何优化的话,下⾯代码执⾏的结果是啥?

# define _CRT_SECURE_NO_WARNINGS 1
#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;
}

当你看到这个代码时,是否观察到我们定义数组的大小为10,但是我们打印到12,也就是数组arr[10].arr[11],arr[12],这些空间到底有没有创建呢?如果没有那就是非法访问了,编译器会不会报错呢?Ctfl+F5,让程序走起来

代码运行结果:此时代码并没有停止,而是一直在打印,不断死循环,这是为什么呢?

不慌,让我们调试起来:

此时F10走起,按F11慢慢走起来,前面九项没问题:

注:有个小细节 i 和arr[12]是跟着一起动的,

同样跟着走:

接着i=10—>

震惊!arr[10]的值竟然改了,赋值为0了,稍后,我们再解释,先让程序继续走–>

i=11,也把值给改了;

当i=12,arr[12]就等于12了

这是为什么呢?

解析:


栈区内存的使⽤习惯是从⾼地址向

低地址使⽤的,所以变量i的地址是

较⼤的。arr数组的地址整体是⼩

于i的地址。

数组在内存中的存放是:随着下标

的增⻓,地址是由低到⾼变化的。

如果是左边的内存布局,那随着数组

下标的增⻓,往后越界就有可能覆盖

到i,这样就可能造成死循环的。


这⾥肯定有同学有疑问:为什么i和arr数组之间恰好空出来2个整型的空间呢?这⾥确实是巧合,在不同的编译器下可能中间的空出的空间⼤⼩是不⼀样的,代码中这些变量内存的分配和地址分配是编译器指定的,所以的不同的编译器之间就有差异了。所以这个题⽬是和环境相关的。

三、编程常⻅错误归类

3.1 编译型错误

编译错误通常是语法错误。这类错误通常可以通过错误信息找到一些线索,双击错误信息也可以初步跳转到代码错误的位置或附近。随着对语言的熟练掌握,编译错误会变得越来越少,并且更容易解决。

3.2 链接型错误

看错误提⽰信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。⼀般是因为

• 标识符名不存在

• 拼写错误

• 头⽂件没包含

• 引⽤的库不存在

3.3链接型错误

运⾏时错误,是千变万化的,需要借助调试,逐步定位问题,调试解决的是运⾏时问题。

总结

Bug无处不在,在于耐心找出Bug的原因,Bug虽总让人痛苦,但是我们可以利用调试,不断观察到程序内部执⾏的细节,慢慢落小,落细,不断改正,感谢您的观看,如果你觉得对你有所帮助的话,可以给博主一个小小的赞😘

相关文章
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
201 3
|
7月前
|
存储 大数据 Unix
Python生成器 vs 迭代器:从内存到代码的深度解析
在Python中,处理大数据或无限序列时,迭代器与生成器可避免内存溢出。迭代器通过`__iter__`和`__next__`手动实现,控制灵活;生成器用`yield`自动实现,代码简洁、内存高效。生成器适合大文件读取、惰性计算等场景,是性能优化的关键工具。
375 2
|
9月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
411 15
|
存储 编译器 程序员
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
在C语言中,内存布局是程序运行时非常重要的概念。内存布局直接影响程序的性能、稳定性和安全性。理解C程序的内存布局,有助于编写更高效和可靠的代码。本文将详细介绍C程序的内存布局,包括代码段、数据段、堆、栈等部分,并提供相关的示例和应用。
708 5
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
1674 13
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
530 12
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
516 7
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
552 11
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
556 6
|
大数据 C语言
C 语言动态内存分配 —— 灵活掌控内存资源
C语言动态内存分配使程序在运行时灵活管理内存资源,通过malloc、calloc、realloc和free等函数实现内存的申请与释放,提高内存使用效率,适应不同应用场景需求。