一段神奇的c代码错误分析
源代码
#include <stdio.h>int main(int argc, char* argv[])
{int i = 0;int arr[3] = {0};printf("first i is %p\n", &i);printf("first arr loc is %p\n", &arr);for (; i < 3; i++){printf("arr %d loc is %p\n", i, &arr[i]);printf("i:%d loc is %p\n", i, &i);arr[i] = 0;printf("hello world\n");}return 0;
}
输出
在centos7 的机器上编译然后输出得到
first i is 0x7ffd1a10d21c
first arr loc is 0x7ffd1a10d210
arr 0 loc is 0x7ffd1a10d210
i:0 loc is 0x7ffd1a10d21c
hello world
arr 1 loc is 0x7ffd1a10d214
i:1 loc is 0x7ffd1a10d21c
hello world
arr 2 loc is 0x7ffd1a10d218
i:2 loc is 0x7ffd1a10d21c
hello world
神奇的地方来了
将
for (; i < 3; i++)
改成
for (; i <= 3; i++)
现在再编译输出会无限循环输出,截取其中的一段得到:
first i is 0x7ffd1a10d21c
first arr loc is 0x7ffd1a10d210
arr 0 loc is 0x7ffd1a10d210
i:0 loc is 0x7ffd1a10d21c
hello world
arr 1 loc is 0x7fff75ecb214
i:1 loc is 0x7fff75ecb21c
hello world
arr 2 loc is 0x7fff75ecb218
i:2 loc is 0x7fff75ecb21c
hello world
arr 3 loc is 0x7fff75ecb21c
i:3 loc is 0x7fff75ecb21c
hello world
arr 1 loc is 0x7fff75ecb214
i:1 loc is 0x7fff75ecb21c
hello world
arr 2 loc is 0x7fff75ecb218
i:2 loc is 0x7fff75ecb21c
hello world
arr 3 loc is 0x7fff75ecb21c
i:3 loc is 0x7fff75ecb21c
.....
为什么会发生这种现象呢?
究其原因是因为
函数体内的局部变量是存在栈上的,且是连续压栈。在Linux进程的内存布局中,栈区在高地址空间,从高向低增长。变量i和arr在相邻的地址,其i比arr的地址大,由于我们只声明数组大小为3,所以如果访问arr[3]其实已经越界了,但是虽然arr[3]是不存在的,但是如果越界访问的话我们可以发现他的地址是0x7fff75ecb21c
,这和其实就是i
的地址。
所以:
arr[3] = 0;
其实就是
i = 0
所以会一直进入死循环的情况。
一段神奇的c代码错误分析相关推荐
- 一行神奇的javascript代码
一行神奇的javascript代码 一行神奇的JS代码,是在一个博客园里面看到的,当时我就震惊了,这不就是传说中的ZB神奇么- - 哈哈(果断转载过来). 写本篇文章的缘由是之前群里@墨尘发了一段js ...
- 16位代码段与32位代码段的区别
16位代码段与32位代码段的区别: 16位代码段与32位代码段的区别如下: 16位代码段最长只能为64k,段内偏移量为16位,默认的指令地址及操作地址为16位: 32位代码段最长可以4G,段内偏移量 ...
- 特权级——保护模式的特权级检查 DPL,RPL,CPL, 一致代码段,非一致代码段
特权级是保护模式下一个重要的概念,CPL,RPL和DPL是其中的核心概念,查阅资料无数,总结如下. 一.CPL.RPL.DPL简单解释 CPL是当前进程的权限级别(Current Privil ...
- 一致代码段与非一致代码段
首先,我们先来看几个问题: 一致代码段和非一致代码段是什么? 为什么要有一致代码段和非一致代码段? 系统提供怎样的机制来使用户程序访问内核数据? 程序如何在段与段之间跳转? 接下来,我们将讨论上述这些 ...
- 统一代码段与非一致代码段
一致代码段与非一致代码段 上几篇文章,我们一直在讨论的都是 GDT 相关的一些问题,现在我们知道在系统在从实模式向保护模式跳转时,GDT 是必须要准备的结构.在介绍这一跳转之前,这篇文章我们来介绍两个 ...
- CPL DPL RPL的区别 一致性代码段和非一致性代码段
概述:在谈论保护模式编程的时候,一直会有这样的困惑:为什么除了CPL和DPL还有RPL?什么时候高特权级不能访问低特权级?什么时候低特权级不能访问高特权级?一致性代码和非一致性代码有什么区别?等等这些 ...
- 一致性代码段和非一致性代码段【转】
一致代码段是内核开辟出来的供应用程序访问的段,但是不允许用户程序写入数据. CPL(Current Priviliege Level):它代表了当前代码段的特权等级,由CS和SS的第0位和第1位表示. ...
- 数据段描述符和代码段描述符(二)——《x86汇编语言:从实模式到保护模式》读书笔记11
这篇博文,我们编写一个C语言的小程序,来解析数据段或者代码段描述符的各个字段.这样我们阅读原书的代码就会方便一点,只要运行这个小程序,就可以明白程序中定义的数据段或者代码段的描述符了. 这段代码,我用 ...
- 数据段描述符和代码段描述符(一)——《x86汇编语言:从实模式到保护模式》读书笔记10
一.段描述符的分类 在上一篇博文中已经说过,为了使用段,我们必须要创建段描述符.80X86中有各种各样的段描述符,下图展示了它们的分类. 看了上图,你也许会说:天啊,怎么这么多段描述符啊!我可怎么记住 ...
最新文章
- pyqt4+chatterbot实现简单聊天机器人程序
- CSS魔法堂:重拾Border之——更广阔的遐想
- 后缀数组总结(转载)
- 限制输入框只能输入数字
- Spark Streaming事务
- getset原子性 redis_Redis 分布式锁进化史解读 + 缺陷分析
- 响应json数据之过滤静态资源
- 利用matlab实现SAR 图像线性拉伸显示
- 乔布斯死后的300亿遗产终于被败光了,没想到竟是干了这件事
- oracle outln用户,Oracle用户解锁
- 计算机学硕英语考什么意思,计算机考研都考什么?
- Linux mint 14下的powerDNS+mysql+powerAdmin搭建个性DNS域名解析服务器
- 高通msm8909 平台camera 系统软件架构
- 操作系统:Win10如何彻底卸载自带的Flash软件
- The serializable class Myplayer does not declare a static final serialVersionUID field of type long
- 深度学习 视频目标跟踪
- µC/OS-II Release Notes
- 苹果严打iMessage垃圾短信
- 分享一款程序员起名神器,让你从此起名不再头秃
- 硬件设计——关于电路设计的一些知识