问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

判断数组越界,除了用if还可以有其他的方法吗

发布网友 发布时间:2022-04-27 08:15

我来回答

2个回答

懂视网 时间:2022-04-27 12:37

前言

前面一篇文章提到过 数组越界行为,虽然编译器为我们做了大量的检查工作让我们避免这些错误。

但是我觉得还是有必要模拟一下数组越界,感受一下这个错误。

那么对于.NET来说我们怎么来模拟数组越界呢?

一、 [VS] 项目 -> 右击 -> 属性 -> 生成 -> (勾选)允许不安全代码

二、测试代码

unsafe private static void OutOfIndexMini()
 {
 int* i = stackalloc int[1];

 i[0] = 0;
 //i[0] = 1;

 //double* d = stackalloc double[1];
 //d[0] = 0.01;

 int* a = stackalloc int[3];

 for (; i[0] <= 3; i[0]++)
 {
 a[i[0]] = 0;

 Console.WriteLine($"int* i = {i[0]}");

 Console.WriteLine($"int* a[{i[0]}] = {a[i[0]]}");
 }

 }

简单说明一下:

unsafe 关键字 -- 支持不安全代码,就是说我们可以使用指针了。

stackalloc 关键字 -- 允许向堆栈申请内存了。

下面这两句:我向内存申请 了数组 int[1],容量为一个int,并同时给这个赋值为1

int* i = stackalloc int[1];

i[0] = 0;

接下来:我紧接着向内存申请了数组 int[3],容量为 3个int.

int* a = stackalloc int[3];

然后注意:我的for循环数组越界了i[0] <= 3

for (; i[0] <= 3; i[0]++)
{
  a[i[0]] = 0;

  Console.WriteLine($"int* i = {i[0]}");

  Console.WriteLine($"int* a[{i[0]}] = {a[i[0]]}");
}

初始值 i[ 0 ] = 0,所以进入for循环

i[0] = 0 >>> a[ i[ 0 ] ] =0 >>>a[ 0 ] =0

i[0] = 1 >>> a[ i[ 0 ] ] =0 >>>a[ 1 ] =0

i[0] = 2 >>> a[ i[ 0 ] ] =0 >>>a[ 2 ] =0

i[0] = 3 >>> a[ i[ 0 ] ] =0 >>>a[ 3 ] =0 ?

此时 a[ 3 ] 对于我们平常来说已经数组越界了,但是这里仍然可以正常赋值。那这个值我们给了谁?

我们先给出一个答案:

  a[3] 其实越界到了 i[0] 地盘,也就是 a[3] = i[0] = 0,

  这就造成 当 i[0] = 3 时,a[3] 越界将 i[0] 修改为0,程序进入死循环 ... ...

三、验证

如果,我将 i[0] 初始值修改一下,改成1

int* i = stackalloc int[1];

//i[0] = 0;
i[0] = 1; 

那么在越界后a[3] = i[0] = 0 ,打印出来 i [0] = 0 说明数组确实越界并修改了值。

那么,我在中间再声明一个不是int类型的数组,导致越界不是修改的 i[0] 这样就不会死循环了。

int* i = stackalloc int[1];

//i[0] = 0;
i[0] = 1;

double* d = stackalloc double[1];
d[0] = 1;

int* a = stackalloc int[3];

四、原理分析

因为数组是相同的数据类型,连续内存。

第一次:i=0 ,a[0] 内存地址 1000

第二次:i=1 ,a[1] 内存地址 1004

第三次:i=2 ,a[2] 内存地址 1008

第四次:i=3 ,a[3] 内存地址 1012,也就是越界到了 i[0]

总结

热心网友 时间:2022-04-27 09:45

1. ArrayIndexOutOfBoundsException是运行时异常, 编译器是不会知道的, 只有运行时jvm才能捕获到
2. jvm为何能捕获到,数组在运行时是由jvm创建的一个东西,是用机器指令创建的。。。 类似于汇编指令, 先根据你声明的长度分别为每个元素赋值,压栈, 而对于数组的长度也是由一个特定的指令来得到的, 也会压到栈中。这就是你为什么能用a.length得到数组长度的原因, 并且jvm在读写数组元素时都会有与数组长度比较的指令, 如果越界则抛出异常
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
LOL9.20版本余震辅助狗熊怎么玩_9.20版本余震辅助狗熊玩法攻略_百度... 英雄联盟的狗熊怎么出装 英雄联盟狗熊的出装 张医师你好,我干喷漆的工作没几天手指就好痒是什么原因啊? ...疼,就是又疼又痒的感觉!请问是怎么回事?怎么治! ...白酒和啤酒后第二天发现手掌痒,然后按的话有点疼,以前没有出现过这种... 芦苇有哪些用处 芦苇有哪些用途 芦苇多少用处 乾安1.2.3.4.5路公交车路线图 我用的java的jxl,把从数据库里面查询的一个list集合导出excel文件,内容是乱码文件名是对的 单层钢结构节间安装优点有哪些? 钢结构安装工程监控工作主要有哪些? 吊具钢结构的螺栓应选用的强度等级为多少? 300MW的机组,锅炉钢架吊装主要能遇到什么问题,是怎么解决的 钢结构厂房彩钢夹芯墙板安装使用什么样的吊索具 在装配式钢结构的吊点与吊具设计中,长度较大的钢梁一般设置几个吊点? vb.net中split函数数组越界的问题! 拼音怎样读(如:王字是用那几个拼音组成的,怎么读等) 如:一个字的拼音怎么读怎么写我不会. 怎样写拼音 拼音如何写 关于爱国的儿歌 请问这个放纸杯蛋糕上面装饰的树叶叫什么名字。一般做甜品蛋糕装饰还可以用到那些植物叶子 南宁哪个蛋糕店的蛋糕比较好吃且不太贵? 洗衣机脱水桶内积水怎么办 塑料粉碎机刀片 屹立牌中药粉碎机,怎么换备用刀片? 打粉机的注意事项 关于数组越界,有没有什么好办法 wps高手,谁能告诉我为什么拉不出序列号?是哪里的设置? 如何双方面解除QQ好友关系 什么是开光,开光的东西有什么禁忌 转让股票所得收益的会计分录怎么做 车被冰雹砸了保险赔吗下一年会增加险金吗 开光后的玉坠忌讳什么 开光的东西有什么禁忌去哪里开光 国产免费杀毒软件排名 还贷中的房子怎么卖?我之前还的贷款能从买房人那里收回来吗? 谁知道中国人均平均收入前八位及后八位的省份? 北京人均存款超20万元,这个人均水平在全国排第几? 用下列词语的2个意思造句 融资买入委托价格能高于市场价格吗 .net索引超出了数组界限。麻烦帮我看看怎么解决,谢谢!! 用姜水泡脚后,整个脚特别痒,都痒了半个小时了,怎么办? 姜水泡脚的时候浑身刺痒是怎么回事 姜水泡脚脚痛,怎么回事??? 为什么用热水泡脚会痒 如何使用e宝通 酷派大神f2如何实现usb网络wifi共享 酷派大神F2怎么使用WIFI热点功能