前面一篇文章提到过 数组越界行为,虽然编译器为咱们作了大量的检查工做让咱们避免这些错误。数组
可是我以为仍是有必要模拟一下数组越界,感觉一下这个错误。安全
那么对于.NET来讲咱们怎么来模拟数组越界呢?ide
1 unsafe private static void OutOfIndexMini() 2 { 3 int* i = stackalloc int[1]; 4 5 i[0] = 0; 6 //i[0] = 1; 7 8 //double* d = stackalloc double[1]; 9 //d[0] = 0.01; 10 11 int* a = stackalloc int[3]; 12 13 for (; i[0] <= 3; i[0]++) 14 { 15 a[i[0]] = 0; 16 17 Console.WriteLine($"int* i = {i[0]}"); 18 19 Console.WriteLine($"int* a[{i[0]}] = {a[i[0]]}"); 20 } 21 22 }
简单说明一下:测试
unsafe 关键字 -- 支持不安全代码,就是说咱们能够使用指针了。spa
stackalloc 关键字 -- 容许向堆栈申请内存了。指针
下面这两句:我向内存申请 了数组 int[1],容量为一个int,并同时给这个赋值为1code
int* i = stackalloc int[1]; i[0] = 0;
接下来:我紧接着向内存申请了数组 int[3],容量为 3个int.blog
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]