c#在默认情况下生成的都是安全代码,即进行了代码托管(.NET的CLR机制好处之一是,进行代码托管,适时的释放内存,程序员便不必考虑资源的回收问题),而此时,指针不能出现在安全代码的编译条件下。

一、unsafe

如果因需要想在c#中使用指针,那么unsafe便是一个通道(当然在使用前,需在项目属性的生成选项中,选择“允许不安全代码”)。

example 1:

a) 创建项目,项目属性->生成->选择“允许不安全代码”

b) 编写代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleDll
{
//此处为c++动态库的调用,因 DllC++.dll是示例测试文件,为不影响代码演示,此处屏蔽
//public class Code
//{
// [DllImport("DllC++.dll")]
// public unsafe static extern int Add(int a, int* b);
//}
class Program
{
public unsafe static int Add(int a, int* b)//此处使用 指针,需要加入非安全代码关键字unsafe
{
return a + *b;
}
static void Main(string[] args)
{
unsafe//此代码块为非安全代码,可以使用指针
{
int resDll,resInner, a;
int* b;//如果在安全代码条件下,编译不会通过对指针的定义
a = 1;
b = &a;
// resDll = Code.Add(a, b);
resInner = Add(a,b);
}
}
}
}

  上面代码简单的示范了何种情况下可以使用指针。

二、fixed

fixed其实是在非安全代码下用到才会有意义的。因为他负责对指针所指向的“动态分配内存的对象或对象中的成员”简称“对象”进行锁定(之所以要锁 定,是因为即使在非安全代码模式下,这些对象一样的使用CLR的代码托管,这样的话,很可能造成对象的地址变动,就是因为CLR对资源重新分配的不确定 性,假使指针在未完成对对象的操作时,对象地址变动,那么指针指向的地址就会出现混乱,很可能造成内存泄漏甚至系统崩溃。如果使用fixed进行锁定,那 么只有在执行完fixed模块后,指针所指向的对象才能被移动)。

a) 垃圾回收机制,维护引用信息不维护指针信息

b) 引用类型的实例化对象在生存期内由垃圾回收机制处理,可能移动内存

c) 当一个类的实例化对象中含有值类型时,定义指向这些值类型的指针编译报error,因为这些内嵌在引用类型中的值类型实例会随着引用实例化对象的内存移动而移动,所以指针值在不知情的情况下会发生变化,fixed关键字做的工作便是让这样的类实例化对象(不是类类型本身,而是一个实例化对象)

example 2:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleDll
{   //例子1

    unsafe void SquarePtrParam(int* p)
    {

      *p *= *p;

    }

    public unsafe void run()

    {

       int[] arr = new int[] { 1, 2, 3, 4, 5 };

      fixed (int* p = &arr[0]) //此处将锁住arr[0],使得在fixed操作块内,arr[0]不会被CLR移动

      {

        for (int i = 0, n = arr.Length; i < n; i++)

        { 

          SquarePtrParam(p + i);

          Console.WriteLine(p[i]);

        }

      }

    }    

    //例子2
        public static int Add(int[] a,int b)
{
unsafe
{
fixed (int* pa = a)//此处将锁住a,使得在fixed操作块内,a不会被CLR移动
{
return *pa + b;
}
} }
static void Main(string[] args)
{
int[] a = new int[1];
a[0] = 1;
int b = 2;
int res = Add(a,b);
}
}
}

  上述代码需注意的是:pa的地址也是被固定了的,所以不能对他进行赋值操作。    

C# 指针(unsafe与fixed的使用)的更多相关文章

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

    指针C#unsafefixed 目录(?)[-] 概述 unsafe fixed 1.1 概述 unsafe关键字表示不安全上下文,该上下文是任何涉及指针的操作所必需的.可以在属性.方法.类的声明中使 ...

  2. C#中的Unsafe和Fixed

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

  3. Unity3D 使用C#指针unsafe

    Unsafe code requires the `unsafe' command line option to be specified 在Unity开发中,如果涉及到指针的使用,需要自己定义预处理 ...

  4. C#通过unsafe来操作指针

    这里不介绍unsafe的理论,这里单单介绍它的用法.如果要了解的更具体,可以看这篇大神的博文:C#通过指针操作图像 先从一个很简单的例子介绍: private void TestInptr() { u ...

  5. C#中指针的用法

    (*) unsafe 和 fixed unsafe { ]; ; i < array.Length; i++) { array[i] = i; } fixed (int* p = array) ...

  6. C# unsafe code

    (*) unsafe 和 fixed unsafe {                    ];     ; i < array.Length; i++)     {         arra ...

  7. [.net 面向对象编程基础] (7) 基础中的基础——流程控制语句

    [.net 面向对象编程基础] (7) 基础中的基础——流程控制语句 本来没有这一节的内容,后来考虑到既然是一个系列文章,那么就尽可能写的详细一些,本节参考了网上朋友所写的例子,为的是让更多小伙伴学习 ...

  8. 继续SecureString

    上回写了关于SecureString的特征和为什么我们要使用它,这篇继续研究研究这个SecureString. **主要内容:** - SecureString与String之间的转换 - Secur ...

  9. C#联合Union的实现方式

    一.基础篇 C#不像C++,他本身是没有联合Union的,但是可以通过手动控制结构体每个元素的位置来实现,这需要结合使用StructLayoutAttribute.LayoutKind以及FieldO ...

随机推荐

  1. 如何创建,增加swap

    使用分区做为SWAP比较好,速度比文件的快,也不容易产生磁盘碎片所有应该尽量使用分区作为SWAP. 先说说使用文件做为SWAP吧:一.因为做为SWAP的文件,必须是连续的,所以需要使用dd命令创建:[ ...

  2. java jvm学习笔记四(安全管理器)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一 ...

  3. jvm常量池 vsv为什么1000 == 1000返回为False,而100 == 100会返回为True?

    在jvm规范中,每个类型都有自己的常量池.常量池是某类型所用常量的一个有序集合,包括直接常量(基本类型,String)和对其他类型.字段.方法的符号引用.之所以是符号引用而不是像c语言那样,编译时直接 ...

  4. 《深入Java虚拟机学习笔记》- 第14章 浮点运算

    <深入Java虚拟机学习笔记>- 第13章 浮点运算

  5. 《深入Java虚拟机学习笔记》- 第7章 类型的生命周期/对象在JVM中的生命周期

    一.类型生命周期的开始 如图所示 初始化时机 所有Java虚拟机实现必须在每个类或接口首次主动使用时初始化: 以下几种情形符合主动使用的要求: 当创建某个类的新实例时(或者通过在字节码中执行new指令 ...

  6. delphi 数据导出到word

    procedure TFrmWeekAnalysisQry.BtnExportToExcelClick(Sender: TObject);var wordApp,WordDoc,WrdSelectio ...

  7. HDU 5628 Clarke and math Dirichlet卷积+快速幂

    题意:bc round 72 中文题面 分析(官方题解): 如果学过Dirichlet卷积的话知道这玩意就是g(n)=(f*1^k)(n), 由于有结合律,所以我们快速幂一下1^k就行了. 当然,强行 ...

  8. e2e 自动化集成测试 环境搭建 Node.js Selenium WebDriverIO Mocha Node-Inspector

    Node.js已经出来了许多年载,至今才开始接触.周未在家闲来无事,一时心血来潮,Google了大量的文章,经过实验,终于可以把整个环境给搭起来, 废话不多话,请看步骤. 特别注意, 本文章是针对Wi ...

  9. Zabbix探索:LDAP的认证方式

    这两天部署了Zabbix测试环境,终于用Puppet部署完成了.总是存在一些小问题,如服务不起动啦之类的. LDAP验证方式配置 刚刚配置Zabbix的用户管理,使用LDAP方式认证. 比较惊喜的是L ...

  10. Linux Vi 删除全部内容,删除某行到结尾,删除某段内容 的方法

    1.打开文件 vi filename 2.转到文件结尾 G 或转到第9行 9G 3.删除所有内容(先用G转到文件尾) ,使用: :1,.d 或者删除第9行到第200行的内容(先用200G转到第200行 ...