前言
前一篇文章提到了数组越界行为,尽管编译器为我们做了大量的检查工作来避免这些错误。
但是我觉得有必要模拟一下阵列交叉,感受一下误差。
所以对于。NET,我们如何模拟数组交叉?
一、[VS]项-右键-属性-生成-(勾选)允许不安全代码
二、测试代码
不安全的私有静态void OutOfIndexMini(){ int * I=stack alloc int[1];I[0]=0;//I[0]=1;//double * d=stack alloc double[1];//d[0]=0.01;int * a=stack alloc int[3];for(;I[0]=3;I[0]){ a[I[0]]=0;控制台。write line($ ' int * I={ I[0]} ');控制台。write line($ ' int * a[{ I[0]}]={ a[I[0]]} ');}}简要说明:
Unsafe关键字-支持不安全代码,这意味着我们可以使用指针。
Stackalloc关键字-允许来自堆栈的内存请求。
下面两句话:我从内存中申请了一个数组int[1],容量是一个int,同时这个被赋值为1
int * I=stack alloc int[1];I[0]=0;接下来:我从内存中申请了一个容量为3 ints的数组int[3]。
int * a=stack alloc int[3];然后注意:我的for循环数组越界了。i[0]=3
for(;I[0]=3;I[0]){ a[I[0]]=0;控制台。write line($ ' int * I={ I[0]} ');控制台。write line($ ' 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=stack alloc int[1];//I[0]=0;I[0]=1;然后一个[3]=i[0]=0越过边界后,打印出来的i[0]=0表示数组真的越过边界并修改了值。
然后,我在中间声明了另一个非int类型的数组,这将导致与修改后的i[0]交叉,这样就不会有循环。
int * I=stack alloc int[1];//I[0]=0;I[0]=1;double * d=stack alloc double[1];d[0]=1;int * a=stack alloc int[3];
四、原理分析
因为数组是相同的数据类型,所以连续内存。
第一次:i=0,a[0]内存地址1000
第二次:i=1,a[1]存储器地址1004
第三次:i=2,a[2]内存地址1008
第四次:i=3,a[3]存储地址1012,即i[0]被越过
摘要
以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。