C语言编译器不检查数组下标越界
这两天被人问了一个问题说假如C/C++访问下表越界的数组元素会报错么,于是充满好奇心的我动手试了一下,WTF,果然没有报错,但是会给程序带来莫名其妙的结果(比如十次的循环但是变成了死循环,但八次却可以)
例:
#include<stdio.h>
#include<stdlib.h> //int A[5]={0};
int main()
{
int A[]={};
//int *A=(int*)calloc(5,sizeof(int));
for(int i=;i<;++i)
{
//A[i]=1;
printf("%d\n",A[i]);
} return ;
}
程序结果:

C语言的编译器是不检查下标越界的,以前知道这个问题,可是没有想过是什么原因?
总结如下:
1,不检查下标是否越界可以有效提高程序运行的效率,因为如果你检查,那么编译器必须在生成的目标代码中加入额外的代码用于程序运行时检测下标是否越界,这就会导致程序的运行速度下降,所以为了程序的运行效率,C/C++才不检查下标是否越界。
2,不检查下标是为了给程序员更大的空间,也为指针操作带来更多的方便。如果有这个检查的话指针的功能将会大大被削弱,C的数组标识符,里面并没有包含该数组长度的信息,只包含地址信息,所以语言本身无法检查,只能通过编译器检查,而早期的C语言编译器也不对数组越界进行检查,只能由程序员自己检查确保。以及在早期的CRT函数中也不对字符串指针或数组进行越界检查,都是要求程序员确保空间足够,因此也才也才有了在VS2005之后微软提供的安全的CRT函数版本。
自己写了一段检测程序测试这个问题,发现如果数组下标越界了,那么它会自动接着那块内存往后写。想了一下明白了,以前说不允许数组下标越界,并不是因为界外没有存储空间,而是因为界外的内容是未知的。也就是说如果界外的空间暂时没有被利用,那么我们可以占用那块内存,但是如果之前界外的内存已经存放了东西,那么我们越界过去就会覆盖那块内存,导致错误的产生。。。
这样就明白了,所以我们还是需要好好规划数组的下标滴。
C语言好像没有直接取得数组长度的函数,只有取得数组所占内存大小,再除以一个元素占用的内存大小来计算数组长度。
int a[];
printf("%d",sizeof(a)/sizeof(a[]));
C语言编译器不检查数组下标越界的更多相关文章
- C-基础:C语言为什么不做数组下标越界检查
//这段代码运行有可能不报错.]; ;i<;i++) { a[i]=i; } 1.为了提高运行效率,不检查数组下表越界,程序就可以跑得快.因为C语言并不是一个快速开发语言,它要求开发人员保证所有 ...
- C数组下标越界
之前总听说C语言的各种毛病,今天算是遇到一个:数组下标越界 事情经过 两段完成不相干的代码,一段是测温度的,一段是测转速的.两段代码单独运行都没有问题,但是若运行测转速的代码,测温度的数据就会发生错误 ...
- C语言 第七章 数组与字符串
一.数组 1.1.数组的概念 用来存储一组相同类型数据的数据结构.有点像班上放手机的手机袋,超市的储物柜. 特点:只能存放一种类型的数据,如全部是int型或者全部是char型,数组里的数据成为元素. ...
- (待续)C#语言中的动态数组(ArrayList)模拟常用页面置换算法(FIFO、LRU、Optimal)
目录 00 简介 01 算法概述 02 公用方法与变量解释 03 先进先出置换算法(FIFO) 04 最近最久未使用(LRU)算法 05 最佳置换算法(OPT) 00 简介 页面置换算法主要是记录内存 ...
- 第一个C语言编译器是怎样编写的?
首先向C语言之父Dennis MacAlistair Ritchie致敬! 当今几乎所有的实用的编译器/解释器(以下统称编译器)都是用C语言编写的,有一些语言比如Clojure,Jython等是基于J ...
- 【转】自己动手写SC语言编译器
自序 编译原理与技术的一整套理论在整个计算机科学领域占有相当重要的地位,学习它对程序设计人员有很大的帮助.我们考究历史会发现那些人人称颂的程序设 计大师都是编译领域的高手,像写出BASIC语言的BIL ...
- 在线C语言编译器/解释器
在线C语言编译器/解释器 本文介绍两个C语言在线解释器/编译器,这些工具可以提高代码片段检测方便的工作效率,并可以保证这些代码的正确性,而且还可以和别人一起编辑/分享之间的代码,这样可以共同分析代码并 ...
- C语言基础 - 实现动态数组并增加内存管理
用C语言实现一个动态数组,并对外暴露出对数组的增.删.改.查函数 (可以存储任意类型的元素并实现内存管理) 这里我的编译器就是xcode 分析: 模拟存放 一个 People类 有2个属性 字符串类型 ...
- 简单的C语言编译器--概述
在学习了编译原理的相关知识后,逐渐的掌握一个编译器的结构.作用和实现方法.同时,希望自己在不断的努力下写出一个简单的C语言编译器. 实现步骤 词法分析器:将C语言测试代码分解成一个一个的词法单元: ...
随机推荐
- js 参数传递
最近在读<javascript高级程序设计>时碰到了js传递方式的问题,花费了些时间,不过总算明白了. 数据类型 在 javascript 中数据类型可以分为两类: 基本类型值 primi ...
- 使用MYSQL+Redis完成分页读取功能
public function getAnchorByPopularity($page, $pagesize){ //验证参数的正确性 if(!is_numeric($page) || !is_num ...
- shell 转码BIG5 UTF8
BIG-5 轉 UTF-8 若要將一個文字檔從 BIG-5 編碼轉換為 UTF-8 編碼,可以執行: iconv -f BIG-5 -t UTF-8 big5.txt > utf8.txt 其中 ...
- python2.7 关于打印中文的各种方法
目录 str类型的中文 第一种姿势:逐个打印 第二种姿势: json dumps 第三种姿势: repr string_escape 第四种姿势:PEP3140 unicode类型的中文 当str与u ...
- WinForm 数据库无限填充树目录 treeView
我自己想的是处理数据库每一条数据,然后来插入子节点的子节点. 奈何没有插入子节点的子节点的办法,百度来百度去,一看全都是递归. 本来我是绝望的, 但是没办法,老板的需求不能驳回啊,于是就来ctrl c ...
- 常用SQL脚本记录一
20.SUM()和 列+ 统计结果时:如果列里有一行为null,SUM函数会忽略它:如果+,则结果集也为NULL了 19 SUBSTRING (expression,startIndex, endIn ...
- 【BZOJ 3470】3470: Freda’s Walk 期望
3470: Freda’s Walk Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 42 Solved: 22 Description 雨后的Poet ...
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机 后缀自动机 字符串
https://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机是一种可以处理好多字符串的一种数据结构(不像后缀自动机只有处理一到两种的时候比 ...
- SPOJ GSS
GSS1 题目大意:给出一个数列,多次询问区间最长连续子段和 题解:线段树维护区间最长连续子段和gss,区间从最左元素开始的最长连续子段和lgss 区间以最右元素为结尾的最长连续子段和rgss以及区间 ...
- [OpenGL]纹理贴图实现 总结
实现步骤 第一步:设置所需要的OpenGL环境 设置上下文环境 删除已经存在的渲染的缓存 设置颜色缓存 设置帧缓存 清除缓存 设置窗口大小 开启功能 编译shander 使用program 获取sha ...