C#中的Unsafe和Fixed

托管代码 (managed code):由公共语言运行库环境(而不是直接由操作系统)执行的代码。托管代码应用程序可以获得公共语言运行库服务,例如自动垃圾回收、运行库类型检查和安全支持等。这些服务帮助提供独立于平台和语言的、统一的托管代码应用程序行为。

非托管代码(Unmanaged Code):在公共语言运行库环境的外部,由操作系统直接执行的代码。非托管代码必须提供自己的垃圾回收、类型检查、安全支持等服务;它与托管代码不同,后者从公共语言运行库中获得这些服务。 
Unsafe的代码介于这两者之间,它也是在CLR的环境中执行,但是我们可以直接操作内存。只要我们的代码包含下面三个指针操作符之一就需要使用Unsafe关键字:
  • *
  • &
  • ->

例如:

unsafe static void ChangeValue(int* pInt)
    {
        *pInt = 23;
    }

上面的代码由于是在CLR下托管执行,为了减少内存碎片C#的自动垃圾回收机制会允许已经分配的内存在运行时进行位置调整,所以如果我们多次调用的话就可能
导致指针指向其他的变量。比如*pInt为指向一个变量的地址为1001,CLR在重新内存整理分配后该变量就存储在地址为5001的地方。而原来1001的地方可能会
被分配其他变量,要解决这个问题我们就需要使用Fixed关键字。

fixed 语句禁止垃圾回收器重定位可移动的变量。fixed 语句只能出现在不安全的上下文中。Fixed 还可用于创建固定大小的缓冲区。如下面例子:

using System;
class CaryData
{
    public int data;
}

class CProgram
{

    unsafe static void ChangeValue(int* pInt)
    {
        *pInt = 23;
    }

    public unsafe static void Main()
    {
        CaryData cd = new CaryData();
        Console.WriteLine("改变前: {0}", cd.data);        

        fixed (int* p = &cd.data)
        {
            ChangeValue(p);
        }
        Console.WriteLine("改变后: {0}", cd.data);
    }
}

注意要勾选项目属性中生成标签的允许不安全代码。

时间: 2024-10-18 03:08:14

C#中的Unsafe和Fixed的相关文章

C#关键字explicit、implicit、operator 、unsafe 、fixed

今天遇到一些一般不常用,但说不定什么情况下就能用到的C#关键字. 转换关键字 explicit 定义强制转换 // Must be defined inside a class called Fahrenheit: public static explicit operator Celsius(Fahrenheit fahr) { return new Celsius((5.0f / 9.0f) * (fahr.degrees - 32)); } implicit 定义隐性转换 // User-

Java中的Unsafe类

1.Unsafe类介绍 Unsafe类是在sun.misc包下,不属于Java标准.但是很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty.Hadoop.Kafka等. 使用Unsafe可用来直接访问系统内存资源并进行自主管理,Unsafe类在提升Java运行效率,增强Java语言底层操作能力方面起了很大的作用. Unsafe可认为是Java中留下的后门,提供了一些低层次操作,如直接内存访问.线程调度等. 官方并不建议使用Unsafe. 下面是使

抛砖引玉:如何在 React 中使用 semantic-ui 的 fixed menu 和 sidebar

semantic-ui 的 fixed menu 和 sidebar 放在 body 中运行的很好(这是 sui 的默认设计),但是在 react 应用中,组件体系都是放在比较深的地方,很难直接放在body中,这时,问题很多. 基本思路:创建一个 sidebar 组件,以此作为 sidebar 的 context,并将内容全部放到 pusher 部分中. 如此构建,会发现很多问题:navbar 和 sidebar 不再是 fixed,显示问题,滚动问题…… 究其原因,是使用了 css3 tran

C#中的unsafe

为了保持类型安全性,默认情况下,C# 不支持指针算法. 但是,通过使用 unsafe 关键字,可以定义可在其中使用指针的不安全上下文. 有关指针的详细信息,请参阅主题指针类型. 备注 在公共语言运行时 (CLR) 中,不安全代码是指无法验证的代码. C# 中的不安全代码不一定是危险的:只是 CLR 无法验证该代码的安全性. 因此,CLR 将仅执行完全信任的程序集中的不安全代码. 如果你使用不安全代码,你应该负责确保代码不会引发安全风险或指针错误. 不安全代码概述 不安全代码具有以下属性: 可将方

unsafe,fixed与GCHandle

1.unsafe 为了保持类型安全,默认情况下,C# 不支持指针运算. 在公共语言运行库 (CLR) 中,不安全代码是指无法验证的代码.C# 中的不安全代码不一定是危险的,只是其安全性无法由 CLR 进行验证的代码.因此,CLR 只对在完全受信任的程序集中的不安全代码执行操作.如果使用不安全代码,由您负责确保您的代码不会引起安全风险或指针错误. unsafe 关键字表示不安全上下文,该上下文是任何涉及指针的操作所必需的. 可以在 类型或成员,块内 声明中使用 unsafe 修饰符 若要编译不安全

c# 指针unsafe/fixed -- 【一】

指针C#unsafefixed 目录(?)[-] 概述 unsafe fixed 1.1 概述 unsafe关键字表示不安全上下文,该上下文是任何涉及指针的操作所必需的.可以在属性.方法.类的声明中使用unsafe修饰符,此时类型或成员的整个正文范围均被视为不安全上下文. fixed语句用于禁止垃圾回收器重定位可移动的变量,Fixed还可用于创建固定大小的缓冲区,fixed 语句只能出现在不安全的上下文中. 但在C#中使用指针时只能操作struct,不能操作class,不能在泛型类型代码中使用未

Unity3d中C#使用指针(Unsafe)的办法(转)

近日由于在U3D项目中要使用到数据传递(C++ DLL的数据传递给U3D中的C#),其中涉及到需要使用C#的指针.直接编译会出现以下错误Unsafe code requires the 'unsafe' command line option to be specified. 下面是我总结的解决办法: 1.去除MONO编辑器中的Unsafe错误,Assembly-CSharp鼠标右键找到Options->Build->General .Allow 'unsafe' code 打钩.这个只能去除

sun.misc.Unsafe中一些常用方法记录

sun.misc.Unsafe中一些常用方法记录 前情摘要 sun公司提供了可以用于直接操作内存的类,这个类就是sun.misc.Unsafe.因为Java本身是不会涉及到直接操作内存的,Java API也没有提供这些操作,内存管理全部交给虚拟机来做.Sun之所以提供这个类,因为有些功能现有的Java API满足不了,如果没有这个类,可能就没有现在原子类,J.U.C包了,也许也没了各种Concurrent Collection类,可能也没了NIO的堆外内存,所以这个类十分的有用,并且很重要,Su

C#中指针的用法

(*) unsafe 和 fixed unsafe { int[] array = new int[10]; for (int i = 0; i < array.Length; i++) { array[i] = i; } fixed (int* p = array) { for (int i = 0; i < array.Length; i++) { System.Console.WriteLine(p[i]); } } } 指针在c#中是不提倡使用的,有关指针的操作被认为是不安全的(uns