固定的和活动的变量

&fixed将变量分为两类:固定的和活动的。

固定的变量永久的存在并不会被GC的操作影响。(例如局部变量,值参数和间接指针)活动的变量会被GC重新分配位置或是释放(例如对象中的字段,基础数据数组)。

&取固定变量的地址是没有限制的。但是活动变量容易受GC的影响,其地址只能通过fixed来获得,并且地址仅会在整个fixed语句的周期持续有效。

静态字段也是活动变量。还有标记为refout的也是活动变量,即使这个参数是传递给固定参数的。最后,通过间接指针引用的变量总是固定变量。

指针转换

在不安全上下文中,下面的转换是隐式的:

l 从任何指针类型到void*

l null到任何指针类型

除此之外,下面的转换都是显式的:

l 从任何指针类型到另外的指针类型

l sbyte, byte, short, ushort, int, uint, long, or ulong到其他类型

l 从任何类型到sbyte, byte, short, ushort, int, uint, long, or ulong

指针转换并不改变指针的值。也就是说指针转换前后不影响地址的值。

当转换发生后,当结果指针没有按照正确的指针类型排列的话,当访问结果时结果是无法预知的。

下面的例子:

1 charc='A';2 char*pc=&c;3 void*pv=pc;4 int*pi=(int*)pv;5 inti=*pi;//undefined6 *pi=123456;//undefined7 

下面的例子会打印出double8字节的值:

1 usingSystem;2 classTest3 {4 unsafestaticvoidMain() {5 doubled=123.456e23;6 unsafe{7 byte*pb=(byte*)&d;8 for(inti=0; i<sizeof(double);++i)9 Console.Write("{0:X2}",*pb++);10 Console.WriteLine();11 }12 }13 }14 

打印结果取决于endian

指针数组

在不安全上下文中,是允许指针数组的,只有几种用于其转换是允许的:

l 从任何数组类型到System.Array或是实现了其接口的隐式引用类型转换同样适用于指针数组。但是,任何试图通过System.Array或是实现了其接口访问数组元素都会引发一个 运行时错误,因为指针类型不能转化为object

l 从一个一维数组类型S[]System.Collections.Generic.IList<T>或是到其基接口,任何显示或是隐式的转换都是不行的。因为指针类型不能被用作类型参数,还有没有从指针类型到非指针类型的转换。

l System.Array或是实现了其接口到任何数组类型显示引用转换适用于指针数组。

l System.Collections.Generic.IList<T>或是到其基接口到一个一维数组类型T[],任何显示的转换都是不行的。原因同上面第2条。

还有就是对于foreach语句,不适用于指针数组。相反,下面的语句

foreach (V v in x) embedded-statement

中的x是一个数组类型T[,,…,],n是数组的维度减1TV是指针类型,被改写为:

{
      T[,,…,] a = x;
      V v;
      for (int i0 = a.GetLowerBound(0); i0 <= a.GetUpperBound(0); i0++)
      for (int i1 = a.GetLowerBound(1); i1 <= a.GetUpperBound(1); i1++)
      …
      for (int i
n = a.GetLowerBound(n); in <= a.GetUpperBound(n); in++) {
            v
= (V)a.GetValue(i0,i1,…,in);                                embedded-statement}
}

变量a,i0,i1,…对于x或者embedded-statement或者其余部分的代码是不可见的或是不可访问的。变量vembedded-statement中是只读的。如果没有显示转换从TV,那么就会有错误。如果x是个null,就会有空引用异常。

表达式中的指针

在不安全上下文中,一个表达式的值可以来自于一个指针类型;但是在上下文之外,会造成编译时期错误。

间接访问

一元的*表示一个指针,被用来获得指针指向的值。*用在void*类型表达式或是非指针类型表达式时,会造成编译期错误。

*被用在null指针时是由实现来决定的。不能保证在使用时会抛出System.NullReferenceException

如果一个非法的值赋给指针,那么*的行为是不可预知的。

指针成员访问

在指针成员访问P->IP必须是除了void*之外的类型,I同时必须是一个可访问的成员。

P->I效果上相同于(*P).I。例如:

usingSystem;structPoint
{
publicintx;publicinty;publicoverridestringToString() {return"("+x+","+y+")";
    }
}
classTest
{
staticvoidMain() {
        Point point;
unsafe{
            Point
*p=&point;
            p
->x=10;
            p
->y=20;
            Console.WriteLine(p
->ToString());
        }
    }
}
或是:
classTest
{
staticvoidMain() {
        Point point;
unsafe{
            Point
*p=&point;
            (
*p).x=10;
            (
*p).y=20;
            Console.WriteLine((
*p).ToString());
        }
    }
}

指针元素访问

在指针元素访问P[E]中,P必须是除了void*之外的类型,同时E必须能隐式的转换为int, uint, long, or ulong的表达式。

P[E]效果上同*(P + E).例如:

1 classTest2 {3 staticvoidMain() {4 unsafe{5 char*p=stackallocchar[256];6 for(inti=0; i<256; i++) p[i]=(char)i;7 }8 }9 }10 又如:11 classTest12 {13 staticvoidMain() {14 unsafe{15 char*p=stackallocchar[256];16 for(inti=0; i<256; i++)*(p+i)=(char)i;17 }18 }19 }20 

C# 之不安全代码(2)相关推荐

  1. 隐私合规:收集SDK部分介绍

    com.meizu.cloud.pushsdk.SystemReceiver 魅族推送服务是由魅族公司为开发者提供的消息推送服务,开发者可以向集成了魅族 push SDK 的客户端实时地推送通知或者消 ...

  2. IDEA中将代码块封装为方法,IDEA代码重构快捷键

    IDEA中将代码块封装为方法 选中要转换的代码块,快捷键: Windows快捷键:Alt + Shift + M Mac快捷键:Alt + Command + M 如图:

  3. IDEA自定义快捷指令,快捷生成代码、注释

    我们在使用idea时会发现有非常多的代码生成间接指令,比如输出指令.建主函数指令等等,只需要一个回车,代码就出来了,那我们能不能自定义这些东西呢?答案如下: 第一步,添加一个自定义组 第二步,单击新建 ...

  4. Alibaba代码规范插件、FindBugs插件安装及详解,IDEA插件安装,代码规范,代码查错,代码格式规范

    这是帮助开发者规范代码,培养优良的编码习惯的两个IDEA插件

  5. Myeclipse中项目没有代码错误提示,jsp页面无编译迹象?如何解决

    在使用Myeclipse开发项目时,发现jsp页面中嵌入的java代码没有编译的迹象,错误的get方法没有报错,没有报错信息我们如何知道我们开发的内容是正确的呢? 接下来就演示一下如何解决

  6. 十大算法,描述+代码+演示+分析+改进(赶紧收藏!)

    十大算法 1.冒泡排序 ​ (1)算法描述 ​ 冒泡排序是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来.走访数列的工作是重复地进行直到没有再需要 ...

  7. 编写高性能Java代码的最佳实践

    编写高性能Java代码的最佳实践 摘要:本文首先介绍了负载测试.基于APM工具的应用程序和服务器监控,随后介绍了编写高性能Java代码的一些最佳实践.最后研究了JVM特定的调优技巧.数据库端的优化和架 ...

  8. Jquery DIV滚动至浏览器顶部后固定不动代码

    获取元素(这里定位元素A)距离顶部的高度,接着设定scroll滚动的事件,比如超过那个高度,把A的位置设定为fixed,小于该高度,修改回relative. 效果例1 代码如下复制代码 <scr ...

  9. 距离传感器控制灯泡代码_如何使用颜色传感器和超声波传感器检测障碍物和避障...

    上一期的内容中,我给大家介绍了如何使用触碰传感器检测障碍物和避障,今天我们再来说说如何使用颜色传感器和超声波传感器检测障碍物和避障. 使用颜色传感器 在大多数情况下,EV3颜色传感器并不适合用于障碍物 ...

  10. etcd 笔记(05)— etcd 代码结构、各模块功能、整体架构、各模块之间的交互、请求和应答流程

    1. etcd 项目结构和功能 etcd 项目代码的目录结构如下: $ tree ├── auth ├── build ├── client ├── clientv3 ├── contrib ├── ...

最新文章

  1. 具有absolute、relative、fixed的div设置宽度和高度的效果
  2. JRE和JDK的区别分别代表什么
  3. vue 保留两位小数 不能直接用toFixed(2) ?
  4. Python 面试总结
  5. Android 浏览器 —— 使用 WebView 实现文件下载
  6. centos 5.x 安装 zendOptimizer 5.x
  7. MATLAB/simulink控制系统之传递函数模型
  8. linux禁止线程网络,linux – 如何在gdb中禁用新线程/线程退出的消息?
  9. 【知识星球】颜值,自拍,美学三大任务简介和数据集下载
  10. vc6可编译的 linux 源码,Linux 下源码编译FFMEG
  11. dairy-20110419-每日总结
  12. 2013B题碎纸片拼接
  13. 苹果6s强制删除id锁_苹果ID锁安全神话破灭!2分钟就能解锁
  14. 画图软件gliffy
  15. javascript 表单提交和验证的方法
  16. 微信小程序实现点击按钮退出功能
  17. Jest 单元测试术语解析:describe、it、expect、test
  18. 他们如何利用微信赚钱
  19. 数字 IC 技能拓展(14)基于 C 程序的 FFT 设计
  20. 华为云面试指南—FusionAccess

热门文章

  1. 数据结构二:排序(快速排序和堆排序)
  2. 嵌入式设计与开发实践随笔-1
  3. tensorflow随笔-读取图像文件数据(2)-TFRecord
  4. 双赛道近四百万奖金,2021全国人工智能大赛来了!
  5. 【机器学习基础】时间序列基本概念
  6. 真香!2020最新版《神经网络与深度学习》中文版更新完毕,PDF免费开放下载~...
  7. 【Python应用】Python+Kepler.gl轻松制作酷炫路径动画
  8. MobileNet、GhostNet理解及测试
  9. 专访 | 执拗、纯粹的网易阮良,和他的梦想团队
  10. 0315互联网新闻 | 小红书测试短视频产品“hey”;华为与故宫共同打造“5G智慧故宫”...