C#的不安全代码和指针

coffeecato写在前面:
本文来自《果壳中的C# C#5.0权威指南》 第四章 C#高级特性 4.14不安全代码和指针。由于C#中对于指针的使用有诸多不便,翻到了上面这本书,特别介绍了unsafe及fixed关键字的使用。这里做一摘录,方便日后查阅。

不安全代码和指针

C#支持通过标记为不安全和使用/unsafe编译器选项编译的代码块中的指针直接进行内存操作。指针类型主要用来与C语言API进行互操作,但是也可以用来访问托管堆以外的内存,或者分析严重影响性能的热点。

指针基础

对于每一种数值类型或指针类型V,它们都有对应的指针类型V*。指针实例保存了值的地址。这可以认为是类型V,但是指针类型可以(不安全地)转换到其他任意指针类型。主要的指针运算符有:

运算符作用
&取地址运算符返回指向某个值的地址的指针
*引用运算符返回指针地址所指的值
->指向成员的指针运算符是一个快捷语法,其中x->y等同于(*x).y

不安全代码
使用unsafe关键字标记一个类型、类型成员或语句块,就可以在该范围内使用指针类型和对内存执行C++中的指针操作。下面的例子使用指针实现一个位图的快速处理:

unsafe void BlueFilter(int[,] bitmap)
{
    int length = bitmap.Length;
    fixed(int* b = bitmap)
    {
        int* p = b;
        for (int i = 0; i < length; i++)
            *p++ &= 0xFF;
    }
}

不安全代码与对应的安全实现相比运行速度更快。在这个例子中,代码需要使用一个遍历数组索引和检查边界的嵌套循环。一个不安全的C#方法的执行速度可能比调用外部C函数更快一些,因为它不会出现由于离开托管堆的执行环境而造成负载。

fixed语句

fixed语句是用来锁定托管对象的,如前面例子中的位图。在程序的执行过程中,许多对象都是从堆中分配和回收的。为了避免内存浪费或碎片,垃圾回收器会移动这些对象。因此,如果一个对象的地址在引用时发生变化,那么指向该对象的指针就变成无效的了,所以fixed语句会告诉垃圾回收器“锁定”这个对象,而且不要移动它。由于这可能对运行时效率产生一定的影响,所以fixed代码块只能短暂使用,而且堆分配应避免出现在fixed代码块中。
在一个fixed语句中,可以获得一个指向任意数值类型、数值类型数组或字符串的指针。对于数组和字符串,这个指针实际上是指向第一个元素,它是一种数值类型。
在引用类型中以内联方式声明的数值类型是要求锁定该引用类型的,如下所示:

    class Test
    {
        int x;
        static void Main()
        {
            Test test = new Test();
            unsafe
            {
                fixed(int* p = &test.x)
                {
                    *p = 9;
                }
                System.Console.WriteLine(test.x);
            }
        }
    }

指向成员的指针运算符
除了&和*运算符,C#还支持C++中的->运算符,可以在结构体中使用:

    struct Test
    {
        int x;
        unsafe static void Main()
        {
            Test test = new Test();
            Test* p = &test;
            p->x = 9;
            System.Console.WriteLine(test.x);
        }
    }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值