【C#】不安全代码中的指针用法
2009-09-24 13:46
330 查看
有人说:"有的女人就像c#,长得很漂亮,但家务活不行。" 呵呵,其实我倒是认为不是那个女人不行,而是那个男人不行,征服不了那个女人。C#长得的确算漂亮,如果你驾驭了它,一样能让它服服帖帖做好家务。
对于习惯C的程序员,Java之类的面向对象编程语言用着不是很爽,很多直接访问内存的操作行不通。而C#提供了指针的机制,以满足C族程序员的这点嗜好。不过刚开始了解到C#支持指针的时候,我也不以为然,总觉得这么搞显得不伦不类的。经过一番研究,慢慢感觉到了在一个有着强大基础类库的OO语言中使用指针的价值和威力。下面用代码展示一下使用指针的一些常用操作在C#中是怎么玩的,由于仅仅是展示,所以杂七杂八的代码全放在一起了。
在C#中想要使用指针,要给类型、方法或者代码段加上unsafe关键字,并且编译的时候要加上/unsafe选项。在Visual Studio 2005中,勾上“项目属性->生成”里的“允许不安全代码”,编译时就会自动加上/unsafe选项。
C#中的指针只能指向值类型,并且值类型中不能含有引用类型。如果允许指针指向引用类型,那将是非常令人迷惑的事情。也许你注意到了这行代码:
fixed (byte* bs = new byte[sizeof(Point)])
{
}
它把一个数组赋给了一个指针变量,数组是引用类型,那不是和上面说的矛盾了吗?其实我认为是编译器做了特殊处理,在这里直接将数组的地址赋给了指针变量。一个简单的fixed关键字,编译器在背后肯定做了不少事情。因为引用类型是在托管堆中分配的,受运行库管理,当内存中碎片太多时,垃圾回收器可能会启动内存压缩,有可能将数组移动到别的地方,这时指针指向的就不是原来的数组了,所以fixed作用还在于,把引用类型的数组“钉”在内存的那个位置上,不允许垃圾回收器移动,直到代码执行到fixed后面两个大括号之外为止。
http://www.cnblogs.com/hananbaum/archive/2008/10/30/1323364.html
对于习惯C的程序员,Java之类的面向对象编程语言用着不是很爽,很多直接访问内存的操作行不通。而C#提供了指针的机制,以满足C族程序员的这点嗜好。不过刚开始了解到C#支持指针的时候,我也不以为然,总觉得这么搞显得不伦不类的。经过一番研究,慢慢感觉到了在一个有着强大基础类库的OO语言中使用指针的价值和威力。下面用代码展示一下使用指针的一些常用操作在C#中是怎么玩的,由于仅仅是展示,所以杂七杂八的代码全放在一起了。
1using System; 2 3namespace Sophy.UnsafeCode 4{ 5 unsafe class Program 6 { 7 static void Main(string[] args) 8 { 9 //在栈上分配内存 10 byte* arr_on_stack = stackalloc byte[100]; 11 12 //下标访问数组 13 for (int i = 0; i < 100; i++) 14 { 15 arr_on_stack[i] = 0; 16 } 17 18 //在堆上分配内存 19 fixed (byte* arr_on_heap = new byte[100]) 20 { 21 //指针访问数组 22 for (int i = 0; i < 100; i++) 23 { 24 *(arr_on_heap + i) = 0; 25 } 26 } 27 28 //在栈上分配一个结构体 29 Point p = new Point(); 30 //用结构体指针操作栈上的结构体 31 Point* pp = &p; 32 pp->x = 200; 33 (*pp).y = 300; 34 35 //在堆上分配一个结构体 36 fixed (byte* bs = new byte[sizeof(Point)]) 37 { 38 //用结构体指针操作堆上的结构体 39 Point* ph = (Point*)bs; 40 (*ph).x = 400; 41 ph->y = 500; 42 } 43 44 //打印结构体内存地址 45 Console.WriteLine("pp Memory Address: 0x{0:X}.", ((int)pp).ToString()); 46 47 //识别CPU字节序 48 pp->x = 1; 49 byte* pb = (byte*)&(pp->x); 50 if (1 == *pb) 51 { 52 Console.WriteLine("Your CPU is little endian."); 53 } 54 else if (1 == *(pb + sizeof(int) - 1)) 55 { 56 Console.WriteLine("Your CPU is big endian."); 57 } 58 else 59 { 60 Console.WriteLine("Unkown."); 61 } 62 } 63 } 64 65 unsafe struct Point 66 { 67 public int x; 68 public int y; 69 } 70}
在C#中想要使用指针,要给类型、方法或者代码段加上unsafe关键字,并且编译的时候要加上/unsafe选项。在Visual Studio 2005中,勾上“项目属性->生成”里的“允许不安全代码”,编译时就会自动加上/unsafe选项。
C#中的指针只能指向值类型,并且值类型中不能含有引用类型。如果允许指针指向引用类型,那将是非常令人迷惑的事情。也许你注意到了这行代码:
fixed (byte* bs = new byte[sizeof(Point)])
{
}
它把一个数组赋给了一个指针变量,数组是引用类型,那不是和上面说的矛盾了吗?其实我认为是编译器做了特殊处理,在这里直接将数组的地址赋给了指针变量。一个简单的fixed关键字,编译器在背后肯定做了不少事情。因为引用类型是在托管堆中分配的,受运行库管理,当内存中碎片太多时,垃圾回收器可能会启动内存压缩,有可能将数组移动到别的地方,这时指针指向的就不是原来的数组了,所以fixed作用还在于,把引用类型的数组“钉”在内存的那个位置上,不允许垃圾回收器移动,直到代码执行到fixed后面两个大括号之外为止。
http://www.cnblogs.com/hananbaum/archive/2008/10/30/1323364.html
相关文章推荐
- C#中不安全代码的编写和指针的应用
- c# 不安全代码之指针
- c# 中使用不安全代码操作指针
- C#的不安全代码和指针
- 如何在 C# 中使用不安全代码(使用指针的代码)。
- C# 中使用不安全代码(unsafe、指针)实践
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- [C语言教程]指针转换方式实现C语言的指针操作安全代码
- C#使用指针的代码例程
- C#新手入门代码 LINQ TO XML xattribute的用法示例
- 求new(c#)关键字用法的详细介绍代码示例
- C#安全性之代码访问安全和角色安全小记
- 用代码控制DateTimePicker弹出,C# SendKeys用法
- C#中使用不安全代码
- 在C#的安全环境下使用指针操作
- 编写安全代码:数组和指针的本质以及何时不能互换
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- C#编写不安全代码初探
- c#指针用法示例。
- 编写高质量代码改善C#程序的157个建议[泛型集合、选择集合、集合的安全]