不安全代码

本文详细介绍了C#中指针的隐式转换、显示转换及其特性,包括从任何指针类型转换为void*,使用null转换指针,以及在不安全上下文中使用fixed、stackalloc关键字的情况。同时,讲解了unsafe关键字的作用,以及如何在栈上分配内存。文章还提到了函数指针的使用和垃圾回收器对指针的影响。
摘要由CSDN通过智能技术生成

指针隐式转换具有以下特性
1、任何指针类型都可以转换成void*类型。如:int i = 10; int* pi = &i; void* p = pi;
2、任何null字面值都可以转换成指针类型。如:int* pi = null;

指针显示转换具有以下特性:
1、从任何指针类型转换成任何其他指针类型。如:int i = 10; int* pi = &i; long* pl = (long*)pi;
2、从任何整数类型(sbyte、byte、short、ushort、int、uint、long、ulong)转换成任何指针类型。如:int i = 10; int* pi = (int*)i;
3、从任何指针类型转换成任何整数类型。如:int i = 10; int* pi = &i; int j = (int)pi;

指针具有以下特性:
1、由于垃圾回收器不知道指针及其指向的数据,因此垃圾回收器不会跟踪处理指针。
2、一行代码中声明多个指针变量时,只需在类型后面加上*就可以了,无需在每个变量名称前加上*。
3、指针类型可以作为ref或者out参数进行传递,但是最好不要这样做,因为有可能函数内部对指针类型参数进行赋值后,一旦离开函数作用域就导致指针类型参数指向的地址变成未知内容。
4、指针类型不能作为类型参数,但是指针数组可以作为类型参数。
5、可以使用delegate*来声明函数指针。具有以下特性:
5.1、编译器会使用性能更高的calli指令来调用函数。
5.2、只能在static函数上使用&运算符获取函数的地址。
5.3、可以使用managed关键字来指示函数指针使用托管调用约定;也可以使用unmanaged关键字来指示函数指针使用非托管调用约定。

unsafe关键字具有以下特性:
1、unsafe关键字的作用只是用来引入不安全上下文,进而允许在代码中使用指针类型。
2、unsafe关键字可以应用在类型、成员、局部函数、语句块上面。具有以下特性:
2.1、使用unsafe关键字时,必须使用AllowUnsafeBlocks编译器选项来进行编译。
2.2、当unsafe关键字应用到partial关键字修饰的类型上时,那么就只有该特定部分类型中引入不安全上下文。

fixed关键字具有以下特性:
1、fixed关键字只能出现在不安全的上下文中。
2、fixed关键字可以用来创建固定大小的缓冲区。具有以下特性:
2.1、固定大小缓冲区只能作为结构体的成员。
2.2、固定大小缓冲区不能使用static修饰符。
2.3、固定大小缓冲区的元素类型应该为预定义类型(sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、bool)。
2.4、固定大小缓冲区中每个元素在内存中按顺序排列。
2.5、必须在不安全上下文中访问固定大小缓冲区,并且必须以指针的形式来接收固定大小缓冲区。
3、fixed关键字可以用来创建语句块。具有以下特性:
3.1、在语句块的()里面可以使用指针来临时固定变量的地址。具有以下特性:
3.1.1、当指针指向非托管类型T的静态字段变量时,如果类型T*可以隐式转换为该指针类型,那么初始化程序就会计算指定静态字段变量的固定地址。
3.1.2、当指针指向非托管类型T的实例字段变量时,如果类型T*可以隐式转换为该指针类型,那么初始化程序就会计算指定实例字段变量的固定地址。
3.1.3、当指针指向非托管类型T的数组变量时,如果类型T*可以隐式转换为该指针类型,那么初始化程序就会计算指定数组变量中第一个元素的固定地址。
3.1.4、当指针指向字符串变量时,如果char*类型可以隐式转换为该指针类型,那么初始化程序就会计算字符串变量中第一个字符的固定地址。
3.1.5、在语句块的生命周期内会保证固定变量不会被垃圾回收器进行重定位。一旦语句块执行完毕,那么固定变量就会被解除固定并受到垃圾回收器的制约。
3.1.6、由于固定变量会因为无法进行重定位的原因而出现内存碎片的问题,所以只有在绝对必要或者及其短暂的环境下才考虑使用固定变量。
3.2、在语句块的{}里面不能对指向固定变量的指针进行修改操作。如:不能进行++、–、ref、out等操作。

stackalloc关键字具有以下特性:
1、stackalloc关键字只能出现在不安全的上下文中。
2、stackalloc关键字不能用在catch和finally语句块中。
3、stackalloc关键字可以用来在调用栈上分配E*sizeof(T)大小的内存块,并将T*类型的指针指向新分配的内存块。其中,T为stackalloc关键字关联的非托管类型;E为T的个数。
4、stackalloc关键字分配的内存块不能被显示回收,而是只能在作用域执行完毕后被自动回收。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值