数组的下标越界与内存溢出有关吗_数据量过大数组报下标越界

数组的下标越界与内存溢出有关吗_数据量过大数组报下标越界很相似的两个概念,一不小心就会混淆首先,对两个名词做一个大概的解释:下标越界在引用数组元素时,使用的下标超过了该数组下标的应有范围,但应注意的是:C/C++不对数组做边界检查。可以重写数组的每一端,并写入一些其他变量的数组或者甚至是写入程序的代码。不检查下标是否越界可以有效提高程序运行的效率,因为如果你检查,那么编译器必须在生成的目标代码中加入额外的代码用于程序运行时检测下标是否越界,这

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

很相似的两个概念,一不小心就会混淆

首先,对两个名词做一个大概的解释:

  1. 下标越界
    在引用数组元素时,使用的下标超过了该数组下标的应有范围,但应注意的是:
    C/C++不对数组做边界检查。 可以重写数组的每一端,并写入一些其他变量的数组或者甚至是写入程序的代码。不检查下标是否越界可以有效提高程序运行的效率,因为如果你检查,那么编译器必须在生成的目标代码中加入额外的代码用于程序运行时检测下标是否越界,这就会导致程序的运行速度下降,所以为了程序的运行效率,C / C++才不检查下标是否越界。发现如果数组下标越界了,那么它会自动接着那块内存往后写。
    关于C/C++为什么不对数组的下标是否越界做检查,可以参考:
    http://www.xuebuyuan.com/967089.html
    因为编译器不会自动检测你的数组下标是否越界,而是把这个任务交给了程序员自己,所以我们在写程序,引用数组元素时,一定注意不要让数组的下标越界。
    还有,初学者一定不能忘了数组的下标是从0开始的,不是常识中的从1开始。
  2. 内存溢出
    在初始化数组(给数组元素赋值)时,初始化(赋值)元素的个数超过了数组定义时元素的个数。这里的元素个数就是在定义数组时那个方框框里的数字,对于多维数组来说,元素个数 = 每个方框框里的数字之积。
    当然,求数组元素个数可以用公式:
    数组元素个数 = sizeof(数组名)/sizeof(数组任意一个元素)

用两个具体的例子来看看它们之间的区别:

1、 下标越界

#include <stdio.h>

int main()
{
    int i=10, arr[10];
    int sz = sizeof(arr) / sizeof(arr[0]);
    int index = 0;
    scanf("%d", &index);
    arr[index] = 20;
    printf("arr[%d] = %d\n", index,arr[index]);
    system("pause");
    return 0;
}

数组定义为arr[10],它的下标范围是 0–9 ,超出这个范围就会发生下标溢出
这里写图片描述

这里写图片描述
以上两张图片是在VS2013里面的运行结果,两次输入的下标都会越界,但为什么第一张图报错了(数组下标越界),而第二张没有。
这是因为VS2013这个编译器在处理数组下标时,只认为当引用的下标等于数组元素个数时下标越界(可能是怕初学者把数组下标当成是以0开始的吧),别的情况别不回去检测和处理(当我输入的值大于等于11,程序都不会报错)。

这里写图片描述

这里写图片描述
以上是在VC6.0的运行结果,VS2013不同,VC6.0里报错出现在输入值为11时(当输入12时也会报错),而输入10时并不会报错。
这是因为VC6.0里认为当引用数组元素时,若数组的下标比数组的元素个数大 1 (或大 2)时下标越界,。而对于其余的情况不予检测。

这里写图片描述

而在Linux(CentOS6.5)里面运行时,就是我们开头说的那种下标越界的情况,不管你下标咋越界,我的编译器都不会对数组下标做边界检查。

2、 内存溢出

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h> 

int main()
{
    int count[100], i;
    for (i = 0; i <= 100; i++)
    {
        count[i] = 1;
    }
    system("pause");
    return 0;
}

数组定义为count[100],则数组共有100个元素。这里初始化时,for循环一共循环了101次,所以是要给数组初始化101个元素的值,而数组只有100个元素,这样就导致了内存溢出。

这里写图片描述

VS2013环境下,编译链接运行都可以,但会抛出一个错误—>>数组内存溢出。

这里写图片描述

这是在VC6.0环境下,编译链接运行都可以,但同样会出错。

这里写图片描述

这是在Linux(CentOS6.5)环境下,编译链接运行都可以,但程序停不下来,关闭终端时可以看到程序仍在进行。

因此,虽然数组在C语言中是个很强大的东西,但在应用时一定要注意,千万不要出现下标越界的情况,因为这样会造成不可想象的错误。比如下标越界那个例子中的 i 我定义为10,当在VS2013环境下,我输入的下标值为12,在输出arr[12] = 20 的同时,会把i的值也改为20(VS中定义的两个变量,分配内存时会在两个变量的内存空间之间隔出两个空间,空间大小为整形大小),这样别处再用到 i 时 会得到一个错误的 i 的值,可能机会导致一连串的错误,致使结果与预期相差甚远。同时,在初始化数组时,要注意不要初始化的元素个数,不要超出了定义时的个数。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/180397.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Snap7 西门子S7系列PLC的通信库 简介[通俗易懂]

    Snap7 西门子S7系列PLC的通信库 简介[通俗易懂]目录简介参考Snap7简介Snap7用途适用系统支持语言西门子S7通信介绍Snap7组件Sanp7APISnap7PythonSnap7安装PLC设置连接PLC读取数据发送数据Sanp7C/C++node.js简介最近在开发一个项目,作为技术帝,已经完成工艺、机械设计的设计,项目过多,也是为了让自己更加????叉,就开始尝试做电气制图和PLC编程。结合物联网的发展,有一种想法,将数据传…

    2022年10月23日
  • executescalar mysql_ExecuteScalar()

    executescalar mysql_ExecuteScalar()ExecuteScalar()方法的作用是:执行查询,并返回查询所返回的结果集中第一行的第一列。所有其他的列和行将被忽略。它的返回值时object,若是想判断某条数据在数据库里存不存在便可使用该方法,//sql文privatestringm_str_variationInfo=@”SELECTvariationinfoMngnoFROMsellersandvariationmngtbl…

    2022年6月15日
  • pycharm安装教程并永久激活_pycharm怎么看激活时间

    pycharm安装教程并永久激活_pycharm怎么看激活时间激活前准备工作 配置文件修改已经不在bin目录下直接修改,而是通过pycharm修改 如果输入code一直弹出来,请去hosts里移除jetbrains相关的项目 1.下载新版激活成功教程补丁点击链接:https://pan.baidu.com/s/1TfHEFZBsHzPMaGVOavfWhw提取码:p9bi,并将它放置到pycharm安装目录的\bin目录下(位置可随…

    2022年8月29日
  • linux命令 dstat,dstat命令

    linux命令 dstat,dstat命令dstat命令是一个用来替换vmstat、iostat、netstat、nfsstat和ifstat这些命令的工具,是一个全能系统信息统计工具。与sysstat相比,dstat拥有一个彩色的界面,在手动观察性能状况时,数据比较显眼容易观察;而且dstat支持即时刷新,譬如输入dstat3即每三秒收集一次,但最新的数据都会每秒刷新显示。和sysstat相同的是,dstat也可以收集指定的性能资源,…

    2022年6月18日
  • uboot处理dtb「建议收藏」

    uboot处理dtb「建议收藏」目录uboot处理dtb传递参数给内核dtb地址选择dtb修改移植fdttitle:uboot处理dtbdate:2019/4/2817:18:19toc:true—uboot处理dtb传递参数给…

    2022年10月24日
  • logback配置详解maxhistory(logback配置discrim)

    目录1、根节点包含的属性2、根节点的子节点 2.1、设置上下文名称: 2.2、设置loger、root 正文回到顶部1、根节点&lt;configuration&gt;包含的属性scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生…

    2022年4月11日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号